png.c revision 16ea139d53d867211d3bb0fa859a83de653f687e
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%                                                                             %
211454be7db7a897f42cd40e4165f945d77196a6f8cristy%  Copyright 1999-2012 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*/
4416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/studio.h"
4516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/artifact.h"
4616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/attribute.h"
4716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/blob.h"
4816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/blob-private.h"
4916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/cache.h"
5016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/color.h"
5116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/color-private.h"
5216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colormap.h"
5316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colorspace.h"
5416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colorspace-private.h"
5516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/constitute.h"
5616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/enhance.h"
5716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/exception.h"
5816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/exception-private.h"
5916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/geometry.h"
6016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/histogram.h"
6116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/image.h"
6216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/image-private.h"
6316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/layer.h"
6416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/list.h"
6516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/log.h"
6616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/MagickCore.h"
6716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/memory_.h"
6816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/module.h"
6916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/monitor.h"
7016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/monitor-private.h"
7116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/option.h"
7216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/pixel.h"
7316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/pixel-accessor.h"
7416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/profile.h"
7516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/property.h"
7616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/quantum-private.h"
7716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/resource_.h"
7816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/semaphore.h"
7916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/quantum-private.h"
8016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/static.h"
8116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/statistic.h"
8216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/string_.h"
8316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/string-private.h"
8416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/transform.h"
8516ea139d53d867211d3bb0fa859a83de653f687ecristy#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
13216ea139d53d867211d3bb0fa859a83de653f687ecristy * and PixelInfos all have the same 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
15116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PacketAlpha(pixelpacket) \
15216ea139d53d867211d3bb0fa859a83de653f687ecristy     (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)); \
16516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PacketAlpha((pixelpacket)); \
166bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1678e58efdecda887b08ef730d68290a61081ef2566glennrp
168ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR01PixelRed(pixel) \
16916ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelRed(image,(pixel))) < 0x10 ? \
1708e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1718e58efdecda887b08ef730d68290a61081ef2566glennrp
17254cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelGreen(pixel) \
17316ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelGreen(image,(pixel))) < 0x10 ? \
1748e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1758e58efdecda887b08ef730d68290a61081ef2566glennrp
17654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelBlue(pixel) \
17716ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelBlue(image,(pixel))) < 0x10 ? \
1788e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1798e58efdecda887b08ef730d68290a61081ef2566glennrp
18016ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelAlpha(pixel) \
18116ea139d53d867211d3bb0fa859a83de653f687ecristy        (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
19116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelRGBA(pixel) \
192bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
19354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelRGB((pixel)); \
19416ea139d53d867211d3bb0fa859a83de653f687ecristy        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   }
21716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PacketAlpha(pixelpacket) \
2188e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
21916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xc0; \
22016ea139d53d867211d3bb0fa859a83de653f687ecristy     (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)); \
23416ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PacketAlpha((pixelpacket)); \
235bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2368e58efdecda887b08ef730d68290a61081ef2566glennrp
237ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR02PixelRed(pixel) \
2388e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
23916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
2408e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
24116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
24216ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
24316ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2448e58efdecda887b08ef730d68290a61081ef2566glennrp   }
24554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelGreen(pixel) \
2468e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
24716ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
2488e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
24916ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
25016ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
25116ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2528e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelBlue(pixel) \
2548e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2558e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
25616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xc0; \
25716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
25816ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
25916ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2608e58efdecda887b08ef730d68290a61081ef2566glennrp   }
26116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelAlpha(pixel) \
2628e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2638e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
26416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xc0; \
26516ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image, ScaleCharToQuantum( \
26616ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
26716ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel) ); \
2688e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2698e58efdecda887b08ef730d68290a61081ef2566glennrp
27054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelRGB(pixel) \
271bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
272ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR02PixelRed((pixel)); \
27354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelGreen((pixel)); \
27454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelBlue((pixel)); \
275bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2768e58efdecda887b08ef730d68290a61081ef2566glennrp
27716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelRGBA(pixel) \
278bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
27954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelRGB((pixel)); \
28016ea139d53d867211d3bb0fa859a83de653f687ecristy        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   { \
31416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3158e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
31616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
31716ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3188e58efdecda887b08ef730d68290a61081ef2566glennrp   }
31916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Green(pixel) \
3208e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
32116ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3228e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
32316ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
32416ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3258e58efdecda887b08ef730d68290a61081ef2566glennrp   }
32616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Blue(pixel) \
3278e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
32816ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelBlue(image,(pixel))) \
3298e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
33016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
33116ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3328e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3338e58efdecda887b08ef730d68290a61081ef2566glennrp
33416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03RGB(pixel) \
335bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
336ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR03PixelRed((pixel)); \
33716ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Green((pixel)); \
33816ea139d53d867211d3bb0fa859a83de653f687ecristy        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   }
35816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PacketAlpha(pixelpacket) \
3598e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
36016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xf0; \
36116ea139d53d867211d3bb0fa859a83de653f687ecristy     (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)); \
37416ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PacketAlpha((pixelpacket)); \
375bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3768e58efdecda887b08ef730d68290a61081ef2566glennrp
377ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR04PixelRed(pixel) \
3788e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
37916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3808e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
38116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
38216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3838e58efdecda887b08ef730d68290a61081ef2566glennrp   }
38454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelGreen(pixel) \
3858e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
38616ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3878e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
38816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
38916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3908e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelBlue(pixel) \
3928e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3938e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
39416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xf0; \
39516ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
39616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3978e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelAlpha(pixel) \
3998e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4008e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
40116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xf0; \
40216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
40316ea139d53d867211d3bb0fa859a83de653f687ecristy       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
41316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelRGBA(pixel) \
414bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
41554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelRGB((pixel)); \
41616ea139d53d867211d3bb0fa859a83de653f687ecristy        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   }
43716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PacketAlpha(pixelpacket) \
4388e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
43916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha); \
44016ea139d53d867211d3bb0fa859a83de653f687ecristy     (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)); \
45316ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR08PacketAlpha((pixelpacket)); \
454bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4558e58efdecda887b08ef730d68290a61081ef2566glennrp
456ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR08PixelRed(pixel) \
4578e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4588e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
45916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelRed(image,(pixel))); \
46016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
46116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4628e58efdecda887b08ef730d68290a61081ef2566glennrp   }
46354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelGreen(pixel) \
4648e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4658e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
46616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelGreen(image,(pixel))); \
46716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
46816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4698e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelBlue(pixel) \
4718e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4728e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
47316ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))); \
47416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
47516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4768e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PixelAlpha(pixel) \
4788e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4798e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
48016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))); \
48116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
48216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4838e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4848e58efdecda887b08ef730d68290a61081ef2566glennrp
48554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelRGB(pixel) \
486bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
487ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR08PixelRed((pixel)); \
48854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelGreen((pixel)); \
48954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelBlue((pixel)); \
490bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4918e58efdecda887b08ef730d68290a61081ef2566glennrp
49216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PixelRGBA(pixel) \
493bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
49454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelRGB((pixel)); \
49516ea139d53d867211d3bb0fa859a83de653f687ecristy        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   }
51616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PacketAlpha(pixelpacket) \
5178e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
51816ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).alpha); \
51916ea139d53d867211d3bb0fa859a83de653f687ecristy     (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)); \
53216ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR16PacketAlpha((pixelpacket)); \
533bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5348e58efdecda887b08ef730d68290a61081ef2566glennrp
535ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR16PixelRed(pixel) \
5368e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5378e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
53816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelRed(image,(pixel))); \
53916ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
54016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5418e58efdecda887b08ef730d68290a61081ef2566glennrp   }
54254cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelGreen(pixel) \
5438e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5448e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
54516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelGreen(image,(pixel))); \
54616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
54716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5488e58efdecda887b08ef730d68290a61081ef2566glennrp   }
54954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelBlue(pixel) \
5508e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5518e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
55216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelBlue(image,(pixel))); \
55316ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
55416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5558e58efdecda887b08ef730d68290a61081ef2566glennrp   }
55616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PixelAlpha(pixel) \
5578e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5588e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
55916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelAlpha(image,(pixel))); \
56016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
56116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5628e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5638e58efdecda887b08ef730d68290a61081ef2566glennrp
56454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelRGB(pixel) \
565bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
566ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR16PixelRed((pixel)); \
56754cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelGreen((pixel)); \
56854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelBlue((pixel)); \
569bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5708e58efdecda887b08ef730d68290a61081ef2566glennrp
57116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PixelRGBA(pixel) \
572bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
57354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelRGB((pixel)); \
57416ea139d53d867211d3bb0fa859a83de653f687ecristy        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
63985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
64085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
64185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
64285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
64385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
64485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
64585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
64685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
64785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
64885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
64985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
65085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
65185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
65285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
65385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
65485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
65585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
65685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
65785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
65885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
65985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
66085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
66185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
66285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
66385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
66485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
66585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
66685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
66785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
66885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
66985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
67085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
67185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
67285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
67585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
67685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
67785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
67885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
67985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
68085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
68585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
68685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
68785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
68885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
68985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
69085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
69185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
69285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte 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
90616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
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
93516ea139d53d867211d3bb0fa859a83de653f687ecristy  WritePNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
93816ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteMNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
94216ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteJNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
9460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
947fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
9490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
95016ea139d53d867211d3bb0fa859a83de653f687ecristyLosslessReduceDepthOK(Image *image,ExceptionInfo *exception)
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
97216ea139d53d867211d3bb0fa859a83de653f687ecristy        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            {
101216ea139d53d867211d3bb0fa859a83de653f687ecristy              p=GetVirtualPixels(image,0,y,image->columns,1,exception);
10130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
101416ea139d53d867211d3bb0fa859a83de653f687ecristy              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=
102316ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelRed(image,p)) &&
102416ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelGreen(image,p)) &&
102516ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelBlue(image,p)) ?
10263faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
10270c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
10290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
103116ea139d53d867211d3bb0fa859a83de653f687ecristy                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%                                                                             %
112616ea139d53d867211d3bb0fa859a83de653f687ecristy%   Like IsImageGray except does not change DirectClass to PseudoClass        %
1127dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
1128dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
113016ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType ImageIsGray(Image *image,ExceptionInfo *exception)
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
113216ea139d53d867211d3bb0fa859a83de653f687ecristy  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++)
114816ea139d53d867211d3bb0fa859a83de653f687ecristy        if (IsPixelInfoGray(image->colormap+i) == MagickFalse)
1149dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
1150dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1152bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
115416ea139d53d867211d3bb0fa859a83de653f687ecristy    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
115516ea139d53d867211d3bb0fa859a83de653f687ecristy    if (p == (const Quantum *) NULL)
1156dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
1157dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
1158dbb105fc25903e800273f7e980c0553060858a68glennrp    {
115916ea139d53d867211d3bb0fa859a83de653f687ecristy       if (IsPixelGray(image,p) == MagickFalse)
1160dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
116116ea139d53d867211d3bb0fa859a83de653f687ecristy       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
172316ea139d53d867211d3bb0fa859a83de653f687ecristytypedef struct _PNGErrorInfo
172416ea139d53d867211d3bb0fa859a83de653f687ecristy{
172516ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
172616ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
172716ea139d53d867211d3bb0fa859a83de653f687ecristy
172816ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
172916ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
173016ea139d53d867211d3bb0fa859a83de653f687ecristy} PNGErrorInfo;
173116ea139d53d867211d3bb0fa859a83de653f687ecristy
1732cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
173416ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
173516ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
173616ea139d53d867211d3bb0fa859a83de653f687ecristy
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
174016ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
174116ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
17420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
174316ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
174416ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
174516ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
1746c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy
174716ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
174816ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
174916ea139d53d867211d3bb0fa859a83de653f687ecristy
175016ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,message,
175116ea139d53d867211d3bb0fa859a83de653f687ecristy    "`%s'",image->filename);
17520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1753e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
17548371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
17558371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
17568371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1758faa852bad40107edae19405e76a299057668d795glennrp#else
1759faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1760faa852bad40107edae19405e76a299057668d795glennrp#endif
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1763cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
176516ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
176616ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
176716ea139d53d867211d3bb0fa859a83de653f687ecristy
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
177116ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
177216ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
177316ea139d53d867211d3bb0fa859a83de653f687ecristy
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
17760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
177716ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
177816ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
177916ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
178016ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
178116ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
17820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
178316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1788cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_voidp Magick_png_malloc(png_structp png_ptr,png_uint_32 size)
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1790df0d90e1d3bbfa3956818ac7bf43aa0d008020dccristy  (void) png_ptr;
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1797cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17993bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) png_ptr;
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1810cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_read_raw_profile(Image *image, const ImageInfo *image_info,
181116ea139d53d867211d3bb0fa859a83de653f687ecristy   png_textp text,int ii,ExceptionInfo *exception)
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1813bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1846f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
18470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
184897f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
184997f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
185097f90e23c85b9c58387880125c29d8c99126f83aglennrp
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
185716ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) ThrowMagickException(exception,GetMagickModule(),
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18628723e4bcd840478cecfd29891e792edb499cd0e9cristy  profile=BlobToStringInfo((const void *) NULL,length);
18630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
186616ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) ThrowMagickException(exception,GetMagickModule(),
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
18750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
188216ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) ThrowMagickException(exception,GetMagickModule(),
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
18920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
189916ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProfile(image,&text[ii].key[17],profile,exception);
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
19010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
19040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1938bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
19400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1941bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1989cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tIME chunk into the date:modify property */
1990cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tEXt/Creation Time chunk into the date:create property */
1991cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
19964eb3931feb349dd87142c78503b779228f3e1a0fglennrp    intent,
1997cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
19994eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
2001faa852bad40107edae19405e76a299057668d795glennrp    pass,
2002faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
2003faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
2004faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
2005faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
2006faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
20074eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
20084eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
20094eb3931feb349dd87142c78503b779228f3e1a0fglennrp
20104eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
20114eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
20144383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
201716ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
201816ea139d53d867211d3bb0fa859a83de653f687ecristy    transparent_color;
201916ea139d53d867211d3bb0fa859a83de653f687ecristy
202016ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
202116ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
202216ea139d53d867211d3bb0fa859a83de653f687ecristy
2023faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
2024faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
2025faa852bad40107edae19405e76a299057668d795glennrp
2026faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
2027faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
2028faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
2029faa852bad40107edae19405e76a299057668d795glennrp
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2040faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
2041faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
2042faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
20434eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
20444eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
2045faa852bad40107edae19405e76a299057668d795glennrp
204616ea139d53d867211d3bb0fa859a83de653f687ecristy  QuantumInfo
204716ea139d53d867211d3bb0fa859a83de653f687ecristy    *quantum_info;
204816ea139d53d867211d3bb0fa859a83de653f687ecristy
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2050cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2052bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2053756ae430d36380dfab8ca703538f5922f3796351cristy    ping_rowbytes,
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2059bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
206316ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
206739992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2070eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
2071eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
2072eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
2086fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2089cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
209225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
209861b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
209961b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
210061b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
210161b4c957269727a0a2526edc2331881da8346100glennrp    {
210261b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
210361b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
210461b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
210561b4c957269727a0a2526edc2331881da8346100glennrp    }
210661b4c957269727a0a2526edc2331881da8346100glennrp#  endif
210761b4c957269727a0a2526edc2331881da8346100glennrp#endif
210861b4c957269727a0a2526edc2331881da8346100glennrp
210916ea139d53d867211d3bb0fa859a83de653f687ecristy
211016ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info = (QuantumInfo *) NULL;
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2113a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
2114a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2115a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      "  image->matte=%d",(int) image->matte);
2116a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
21170e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
21180e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
21190e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
21200e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
212116ea139d53d867211d3bb0fa859a83de653f687ecristy  transparent_color.alpha=65537;
21220e319739731741c52a6303723e0c8678a0df5579glennrp
2123cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
21244eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
2125cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
2126cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
213116ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
213216ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
213316ea139d53d867211d3bb0fa859a83de653f687ecristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
2134cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
2135cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
213716ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,&error_info,
2138cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
21440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
21520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2159cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
21600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2161faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2168cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
21730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
21757b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
217616ea139d53d867211d3bb0fa859a83de653f687ecristy          InheritException(exception,exception);
21777b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
21787b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
21790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2185faa852bad40107edae19405e76a299057668d795glennrp
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
21880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2221991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2222991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2223991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2237991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2241faa852bad40107edae19405e76a299057668d795glennrp
2242faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2243faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2244faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2245faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2246faa852bad40107edae19405e76a299057668d795glennrp
2247faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2248faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2249faa852bad40107edae19405e76a299057668d795glennrp
2250faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2251faa852bad40107edae19405e76a299057668d795glennrp
2252faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2254faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
2255faa852bad40107edae19405e76a299057668d795glennrp        {
2256faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
2257faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
2258faa852bad40107edae19405e76a299057668d795glennrp        }
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2260faa852bad40107edae19405e76a299057668d795glennrp
2261faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2263faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2267e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
2268e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
22690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
2272faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
22730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
2276faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
22770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
2280faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2283faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2284faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2289e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2290e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2291e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2292e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2293e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2294e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2295e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2296e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
23050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
2314e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          profile=BlobToStringInfo(info,profile_length);
2315e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          if (profile == (StringInfo *) NULL)
2316e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          {
231716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ThrowMagickException(exception,GetMagickModule(),
2318e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
2319e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy              "unable to copy profile");
2320ad5b0859c3b4c8d56a62fd922c051eab08a518eccristy            return((Image *) NULL);
2321e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          }
232216ea139d53d867211d3bb0fa859a83de653f687ecristy          SetStringInfoDatum(profile,(const unsigned char *) info);
232316ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SetImageProfile(image,"icc",profile,exception);
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
23312ea7a8e883de7623d345f32f90ee99248a4a867ecristy      {
23322ea7a8e883de7623d345f32f90ee99248a4a867ecristy        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
23332ea7a8e883de7623d345f32f90ee99248a4a867ecristy          (mng_info->global_srgb_intent);
23342ea7a8e883de7623d345f32f90ee99248a4a867ecristy      }
23350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2338cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
2339cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
23400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2343e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2348faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2349faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2350faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
23510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2360faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2361faa852bad40107edae19405e76a299057668d795glennrp    {
2362faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2363faa852bad40107edae19405e76a299057668d795glennrp        {
2364faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2365faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2366faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2367faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2368faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2369faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2370faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2371faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2372faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2373faa852bad40107edae19405e76a299057668d795glennrp        }
2374faa852bad40107edae19405e76a299057668d795glennrp    }
23750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2376faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
23870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2393e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2395e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
2396cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
2397cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
2398faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
2399faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
2400faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
2401faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
24023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2404faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2406905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2407905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
24080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2412e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2413e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2417faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2418faa852bad40107edae19405e76a299057668d795glennrp    {
2419faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2420faa852bad40107edae19405e76a299057668d795glennrp        {
2421faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2422faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2423faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2424faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2425faa852bad40107edae19405e76a299057668d795glennrp        }
2426faa852bad40107edae19405e76a299057668d795glennrp    }
2427faa852bad40107edae19405e76a299057668d795glennrp
2428faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
24340881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
243516ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.x=(double) x_resolution;
243616ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.y=(double) y_resolution;
24370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
244116ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.x=(double) x_resolution/100.0;
244216ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.y=(double) y_resolution/100.0;
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
24440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2447e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2448e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2451823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2452faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
24610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2463faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
24690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2470faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
247516ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ThrowMagickException(exception,
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
24803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2482bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2487faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2496faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2497faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
24980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
25003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
25010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
25040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
25070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2508c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2509c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2510c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
251616ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2522bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2523faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2524faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
25260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2527faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2529bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2530bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2531bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
25380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2539bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      /* Scale background components to 16-bit, then scale
2540bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2541bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
2542bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2543bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2544bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    raw ping_background=(%d,%d,%d).",ping_background->red,
2545bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            ping_background->green,ping_background->blue);
25462cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2547bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
25480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2549bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (ping_bit_depth == 1)
2550bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
25510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2552bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        else if (ping_bit_depth == 2)
2553bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
25540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2555bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        else if (ping_bit_depth == 4)
2556bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
25570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2558bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (ping_bit_depth <= 8)
2559bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
25602cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2561bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2562bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2563bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
25642cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2565bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2566bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
25672cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25682cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
25690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25702cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25712cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
25722cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
2573bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
25742cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2575bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2576faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
25770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2578bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2579faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
25800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2581bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2582bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
25830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
258416ea139d53d867211d3bb0fa859a83de653f687ecristy        image->background_color.alpha=OpaqueAlpha;
25852cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2586bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2587bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2588bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2589bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2590bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2591bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2593bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2594a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2595faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2598a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
260335ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
260435ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
260535ef824baa82511126ff0072ae30eee0da9c05a3cristy
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2610f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2612faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2613faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2614faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2615faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2616faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2617faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2623faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2628a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2629a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2630a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2631a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2632a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2633a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2634a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2635a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2636a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
263716ea139d53d867211d3bb0fa859a83de653f687ecristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
263805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2639faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26410f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
26420f111984738842d27d04aed2a3f823d82a943506glennrp              {
26430f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26440f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
26450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26460f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
264716ea139d53d867211d3bb0fa859a83de653f687ecristy                  "    scaled graylevel is %.20g.",transparent_color.alpha);
26480f111984738842d27d04aed2a3f823d82a943506glennrp              }
264916ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.red=transparent_color.alpha;
265016ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.green=transparent_color.alpha;
265116ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.blue=transparent_color.alpha;
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2658faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2663faa852bad40107edae19405e76a299057668d795glennrp
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2665faa852bad40107edae19405e76a299057668d795glennrp
2666faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2667faa852bad40107edae19405e76a299057668d795glennrp
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2672bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2674bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2677faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2678faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2689faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2690faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
269116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
269216ea139d53d867211d3bb0fa859a83de653f687ecristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
269316ea139d53d867211d3bb0fa859a83de653f687ecristy    image->colorspace=GRAYColorspace;
2694faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2695faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2697befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2698befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2699befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2701befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2702befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
270567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
270667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
270767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
270867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2710faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2719bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
27200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
273216ea139d53d867211d3bb0fa859a83de653f687ecristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
27340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2735faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
27440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27456af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27516af6cf1a950b111ad0ac706269a703086693ba71glennrp
275267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
27536af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
27546af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
27556af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
27566af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
27576af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2762bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2765faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
27660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
27690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2778147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2779cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
2780cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
2781147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
2782147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
2783147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2784147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     /* encode ping_width, ping_height, ping_bit_depth, ping_color_type,
2785147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
2786147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27873b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,
27887cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
278916ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.width,height    ",msg,exception);
2790147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27913b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
279216ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.bit_depth       ",msg,exception);
2793147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27943b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_color_type);
279516ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.color_type      ",msg,exception);
2796147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27973b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%d",
2798147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        (int) ping_interlace_method);
279916ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
2800cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
2801147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
28070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28080ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2809347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2810347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28121b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
28131b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28141b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
28151b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2818e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
28203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
28213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2822cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
28270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
28340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
2836cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2837cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
28380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2840cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
2841cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
28420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2843cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
28450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2852faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2859cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
286116ea139d53d867211d3bb0fa859a83de653f687ecristy      if (quantum_info != (QuantumInfo *) NULL)
286216ea139d53d867211d3bb0fa859a83de653f687ecristy        quantum_info = DestroyQuantumInfo(quantum_info);
28630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2864cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
2865cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
28660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
28700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
28727b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
287316ea139d53d867211d3bb0fa859a83de653f687ecristy          InheritException(exception,exception);
28747b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
28757b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
28760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
288016ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info=AcquireQuantumInfo(image_info,image);
288116ea139d53d867211d3bb0fa859a83de653f687ecristy
288216ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
288316ea139d53d867211d3bb0fa859a83de653f687ecristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
28840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2885c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2886c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2887c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2888c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2889c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2890c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
2891c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
28933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2894c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
2895c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2896c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
2897c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
2898c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
289967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if  (MAGICKCORE_QUANTUM_DEPTH == 8)
290067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        int
290167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          depth;
290267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
290367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        depth=(ssize_t) ping_bit_depth;
290467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
2905c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2906c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2907c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2908c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            MagickTrue : MagickFalse;
29090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2910c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
2911c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
2912c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
2913c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
29140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2915c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
2916c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
29170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2918cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
2919c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
292116ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
2922c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
29230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
292416ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
292516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
292616ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
29270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
292816ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
292916ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
293016ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
29310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
293216ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
293316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
293416ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
29350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
293616ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
293716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
293816ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
29390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
294016ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
294116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
294216ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
29433faa9a3fb01696daaf976d595f492cb530bffb21glennrp
2944c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
2945c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2946c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
2947a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
2948a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2949a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
2950a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2951c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
2952c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
29535aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
29545aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
295516ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
2956c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
2957a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2958a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2959a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
2960a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2961c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
2962c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
2963c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
29644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
29654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
296616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
296716ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
296816ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
296916ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
297016ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
297116ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
29724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
2973a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2974a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2975a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
29764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
29774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
29784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
297916ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
2980c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
2981c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
29820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2983c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
2984c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2985c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2986c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
29870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2988c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
2989c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
2990c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
2991c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
2992c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
2993c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
29940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2995c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
29967a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2997c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
29987a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
29997a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
30007a287bfadeadea12e47c2376ca78a5d101687142cristy          }
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3005c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3017c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3018c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3019c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
302016ea139d53d867211d3bb0fa859a83de653f687ecristy
3021faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
30230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
30260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
30290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3030bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3033faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3034c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3037c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3038cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
30400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
304116ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
30430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3044cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3046c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3047faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3051bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3054bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
3057a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3063bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
3064a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
306947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3072bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
3074a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 6) & 0x03;
3075a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 4) & 0x03;
3076a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 2) & 0x03;
3077a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++) & 0x03;
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3082bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
3083a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
308847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3091bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
3093a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 4) & 0x0f;
3094a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++) & 0x0f;
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
3098a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++ >> 4) & 0x0f;
30990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
310247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3105faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3106bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3108a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
310916ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) *p++),q);
311016ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetPixelAlpha(image,q) != OpaqueAlpha)
31110b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
311216ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
31140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3117a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
31180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
312147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3124bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3125a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
3126c17d96f447438bb27d874f1440ed05f6493fde1fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
312758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              size_t
312858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
312958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
313058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3131c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
313258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
313358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3134c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
313558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
313658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3137c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
313858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
31390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3140faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3142c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3143c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3144c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3145c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3146c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3147c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
314816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,ScaleShortToQuantum(quantum),q);
314916ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
315058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
315116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
315258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
315358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
315458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
315558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
315658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
315747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
315858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
315958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
316016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
316116ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
31620b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
316358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
316416ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3167a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
316847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
317147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31753faa9a3fb01696daaf976d595f492cb530bffb21glennrp
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
31800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
318116ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
318216ea139d53d867211d3bb0fa859a83de653f687ecristy
318316ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
318416ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3185bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
318616ea139d53d867211d3bb0fa859a83de653f687ecristy        {
318716ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
318816ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
318916ea139d53d867211d3bb0fa859a83de653f687ecristy        }
31900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
31930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31947a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
31957a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3196cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
31979fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
319847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31997a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
32007a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
32017a287bfadeadea12e47c2376ca78a5d101687142cristy          }
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3203c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32047a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
320747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3211c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3214c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3215c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    image->matte=found_transparent_pixel;
3216c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3217c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3218c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3219c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3220c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3221c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3222c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
32235aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
32245aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32255aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3226bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
32275aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
32285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3229c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3230c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3231c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
323216ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
323316ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
323416ea139d53d867211d3bb0fa859a83de653f687ecristy
32355c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
32365c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3237aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
32385c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
32395c6f789db7a30bad01ace12b09ad9cd471339e94cristy
32405c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
32415c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
324216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3243aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
32445c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
324547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32464eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3249bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3252cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
325416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3256cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
326347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3264faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
3274c11cf6a442f3046940608a5743a68cc891deb13eglennrp
32753c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3276c11cf6a442f3046940608a5743a68cc891deb13eglennrp
32770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
32780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
32790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3280c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
32810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
32820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
328316ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].matte=MagickTrue;
328416ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
328516ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
32860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3287c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
328847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
32900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
32910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
32920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
32930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
329416ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
32950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
329616ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].matte=MagickTrue;
329716ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
32980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
32990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
33000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
330116ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
33020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
330347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3304a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3305a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3306a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
33070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
33080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
33090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
33100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
33110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
33120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3313c11cf6a442f3046940608a5743a68cc891deb13eglennrp
331416ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
33150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3316c11cf6a442f3046940608a5743a68cc891deb13eglennrp
33170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3318a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3319a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3320a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
33210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
33220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
332316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
332416ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
332516ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
332616ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
332716ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
332816ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
33294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
333016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
33314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
33320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
333367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
33340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
33354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
333616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
33374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3338a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
33390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
334016ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
33410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
33420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
33440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3345c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
33460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3347a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3348c11cf6a442f3046940608a5743a68cc891deb13eglennrp
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
33513c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3352eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
33534eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
33544eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3355a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3356a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
33574eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3358a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3359a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33614eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
33624eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
33634eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
33644eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
33650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33664eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
33674eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33684eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
33690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33704eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
33714eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
337216ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) Magick_png_read_raw_profile(image,image_info,text,(int) i,
337316ea139d53d867211d3bb0fa859a83de653f687ecristy              exception);
33744eb3931feb349dd87142c78503b779228f3e1a0fglennrp            num_raw_profiles++;
33754eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
33764eb3931feb349dd87142c78503b779228f3e1a0fglennrp
33774eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
33784eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
33794eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
33804eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
33814eb3931feb349dd87142c78503b779228f3e1a0fglennrp
33824eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
33834eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
33844eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
33854eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
33864eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
338716ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
33884eb3931feb349dd87142c78503b779228f3e1a0fglennrp                  ResourceLimitError,"MemoryAllocationFailed","`%s'",
33894eb3931feb349dd87142c78503b779228f3e1a0fglennrp                  image->filename);
33904eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
33914eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
33924eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
33934eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
33944eb3931feb349dd87142c78503b779228f3e1a0fglennrp
33954eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
33964eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
33974eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
33984eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
33994eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
34004eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
340116ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34034eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
34054eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34064eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      length: %lu",(unsigned long) length);
34074eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34084eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      Keyword: %s",text[i].key);
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
34100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34114eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
341297f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
34134eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
34144eb3931feb349dd87142c78503b779228f3e1a0fglennrp      num_text_total += num_text;
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
34163c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
342973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
34300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
343747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
344216ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ThrowMagickException(exception,GetMagickModule(),
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
34450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
344716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ThrowMagickException(exception,GetMagickModule(),
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
34510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
34580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
346016ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
34610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
34640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
346616ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ThrowMagickException(exception,GetMagickModule(),
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
34690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3470faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
34720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3473faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3474faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3475faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3476faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3477faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3478faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3479faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3480faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
34810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3482faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
34953c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
350147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
35070a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
35080a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp   /* Set image->matte to MagickTrue if the input colortype supports
35090a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
35100a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
35110a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
35120a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
35130a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
35140a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
35150a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        MagickTrue : MagickFalse;
35160a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3517cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3518cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3519cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3520cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3521cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35224eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3523cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3524cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
35253b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3526613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
352716ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text                 ",msg,
352816ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3529cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3530cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3531cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3532cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
35333b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3534cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
353516ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
353616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3537cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3538cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3539cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
35405961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
35413b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
35425961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
354316ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:cHRM                 ",msg,
354416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
35455961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3546cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3547cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
35485961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
35493b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
35505961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
355116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:bKGD                 ",msg,
355216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
35535961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
35545961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
35553b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%s",
35565961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3557cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3558cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
355916ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageProperty(image,"png:iCCP                 ",msg,
356016ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3561cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35624eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
356316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageProperty(image,"png:tRNS                 ",msg,
356416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
35654eb3931feb349dd87142c78503b779228f3e1a0fglennrp
35664eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
3567cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
35684eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
35693b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
357016ea139d53d867211d3bb0fa859a83de653f687ecristy            "intent=%d (See Rendering intent)", (int) intent);
357116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:sRGB                 ",msg,
357216ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
35734eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
35744eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
35754eb3931feb349dd87142c78503b779228f3e1a0fglennrp
35764eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
35774eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
35783b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
357916ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
358016ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
358116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:gAMA                 ",msg,
358216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
35834eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3584cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35854eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3586cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
35874eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
35883b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
358907523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
35904eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
359116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:pHYs                 ",msg,
359216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
35934eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
35944eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3595cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35964eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
35974eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
35984eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
35993b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
36004eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
360116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:oFFs                 ",msg,
360216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36034eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
36044eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
36054eb3931feb349dd87142c78503b779228f3e1a0fglennrp
360607523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
360707523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
360807523c7d2e40370804c2036295571e4b6426f94dglennrp       {
36093b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
361007523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
361107523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
361216ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:vpAg                 ",msg,
361316ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
361407523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3615cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3616cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3622cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3624cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
36300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
364321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
364421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
366147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
366547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3668fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
366916ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
367247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
367547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
368047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3681dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
368347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
368873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
368947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
369247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
370347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
37100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
37180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
372147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
372347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
37290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
373247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
373516ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(image,TrueColorType,exception);
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
374016ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) SetImageType(image,TrueColorMatteType,exception);
37410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
374397f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
374497f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
374597f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
374697f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
374797f90e23c85b9c58387880125c29d8c99126f83aglennrp
374897f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
37500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38024383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
38034383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
38044383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3805bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
382516ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3828bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
383216ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3843bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3857fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
38600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
386116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
38690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
387016ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
38710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
38740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
39020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
39050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3913e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3914e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
39180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
392147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
39250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3929bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
39310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
393447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
394147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3949bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3951bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
395747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
396047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
396547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3969f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
397047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3972f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
397347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
397647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
398047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
398447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
398847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
399247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
399647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
400047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
400647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
400947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
402573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
402647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
402947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
403116ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
40320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
40390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
40430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
405073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
40510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
405616ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
40570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
40680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
40720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
40750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
40840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
40870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
409003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
410747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
411447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
411747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
412647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4134bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
413603812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
415147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
41710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
42018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
42020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
42128182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
42138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
42148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
42158182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
42168182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
42178182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
42188182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
422047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4229e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4230cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
424147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42505eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
42515eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
42520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
425947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
427016ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
427116ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
427516ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
427616ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4287fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
43000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
432316ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
432947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
43330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43343b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
43360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
43390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
43530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
43560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4357bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
435916ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
436116ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
436216ea139d53d867211d3bb0fa859a83de653f687ecristy    {
436316ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
436416ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
436516ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
436616ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
436716ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
436816ea139d53d867211d3bb0fa859a83de653f687ecristy    }
436947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
43730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
43750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
438603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
43900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
43920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
439516ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43973b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
44010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4403bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
440616ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
440847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
441016ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
441116ea139d53d867211d3bb0fa859a83de653f687ecristy               {
441216ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
441316ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
441416ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
441516ea139d53d867211d3bb0fa859a83de653f687ecristy               }
44160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
441816ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
442016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
442116ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
442316ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
442416ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
44260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
443847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
443947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
44450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
44470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
44480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
44490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
44500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
44510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
44530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
44540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
44550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
44560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
44570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
44590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
44600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
44610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
44620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
44660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
44700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
451221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
451321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4533fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
453416ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
45370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
45400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
45430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
454447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
454547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
454747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45483b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
45500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
455147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
455247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
455473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
45550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
45580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
455947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
456047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
45680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
45760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
45800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
458447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
45900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
45930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
45960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46104383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
461121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
461221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
46134383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4620bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
463816ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4645bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4668bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
467738ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
467838ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
467938ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4680bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
470247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
470347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4709fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
471016ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
47130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
47160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
472047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
472147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
472247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
472373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
47240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
47270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
472847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
472947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
473947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
474347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
474447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4747bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
475247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4795e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4796e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
48000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
48030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
48060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
481047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
481347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4814bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
481647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
48260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
482816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
48300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
48370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
483916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
48410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
484647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
48510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
48580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4864bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
48660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4867bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
48690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4873e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4875e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
48798182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
48800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
48830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
48870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
48900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
48948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
48980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
49010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
49040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
490916ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
491147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
491216ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
49130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
49160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
49240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49253b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy            (void) FormatLocaleString(page_geometry,MaxTextExtent,
4926e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4927f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
49280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4930bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4932bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
49340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
49370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
49500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
49548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
49550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
49580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
49670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4969e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
49700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4972e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
498116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
49860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
498816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
499816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
500716ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
50150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
50180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
50250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
50260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
50280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
50290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5033e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
5034f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
50350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5037e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
5038f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
50480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
50550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
50600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
50630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
50660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
50780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
50810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
50860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
50890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
50920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
509316ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
510447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
510747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
510847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
51140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5115bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
512235ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
51310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
51370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
514147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5147bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
515412560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5162bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51658182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
51720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
517947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
518047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
51848182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
51858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
51878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
51898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
51918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
51938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
51958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
520047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
520447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5212e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5213cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
521847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
522247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5225fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
523247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
523547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
523916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
52450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
524947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
52530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
52570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
526047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
526147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
526347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5264bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
526647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
526847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5269bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
528047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
52838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
52848182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
52850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
52878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
52880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5289bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5290bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
52910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
52940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
52960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5299e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
530147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5304bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5305bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
53060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5307bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5308bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
53090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5310bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5311bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
53120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
53150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
53170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5320e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
532247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
53280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5332e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5333e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
533447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
53420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5343bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
53450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5346bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5354e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5355e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
53560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
536047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
536116ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
536316ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
536447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
537147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
53760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
53860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
539616ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
53970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5401e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5402e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
541947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
543147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
545547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
545647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5465bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5468bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
548047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5483bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
548747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
548847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5491bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
550847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
551847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
551947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
55208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
55210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5524e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5525e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
55260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
55290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
554047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
554447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
555647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
55630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5567e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5568f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
556947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
55740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
557947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
559747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
560147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
560516ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
560847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
561147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
56280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
56310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
56340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
564116ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
564547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
565147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
565747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
566047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
566647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
566947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
567547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
567847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
568447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
568747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
569347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
569647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
570247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
570547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
571147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
571547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
571916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
572347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
574247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
574616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
574947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
575247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
575616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
575947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
576247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
576747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
57838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
57858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
578947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
579616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
579847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
580447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
580616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
580947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5812bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5814bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
582247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
582547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
582847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
583147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
583447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
583747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
584047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
584847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
585147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
585447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
585947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
586947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
587647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
587947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
588547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
589347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
58958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5908bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5910bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
591216ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
591716ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
591847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
592547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
592947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
593647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
593947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
594047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
594147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
595016ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5953e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5954e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
596516ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
597016ea139d53d867211d3bb0fa859a83de653f687ecristy              AcquireNextImage(image_info,image,exception);
597147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
597847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
59810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
59830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
599347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
600316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
60040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6008e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6009e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
601347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
601416ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
601916ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
602047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
602747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
60330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
60360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
60450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
60540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
606047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
606447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
606947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6070bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
607147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
608347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
609647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
612947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
613247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
613447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
613547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
613747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61404e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
614147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
614447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
614747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
614947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
615047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
615247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
615647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
615947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
616147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
616247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
616447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61674e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
616847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
617147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
617447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
617647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
617747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
617947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
618916ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
619016ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
619116ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
619216ea139d53d867211d3bb0fa859a83de653f687ecristy
619316ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
619416ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
619516ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
619616ea139d53d867211d3bb0fa859a83de653f687ecristy
6197bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
620116ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
620516ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
620616ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
620847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
620947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
621347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
621416ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
621547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62313faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6239bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
624347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6244bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
624616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
624716ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
624816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
624916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
625016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
625116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
625216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
625316ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
625416ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
625647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
626616ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
626747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
627016ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
627116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
627247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
627547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
627847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
628147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6290e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
629316ea139d53d867211d3bb0fa859a83de653f687ecristy                length=(size_t) image->columns*GetPixelChannels(image);
629416ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
629516ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
629647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
629716ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
629816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
630547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
630847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6309bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6312bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
631347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6314bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6315bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
631647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6317bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6318bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
631947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
632247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6324bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
632547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
632947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6330bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
633647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
633916ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6342bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
63469fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
634716ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
634816ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
634947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6350bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6352fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6361bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
636216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
636316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
636416ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
636516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
636616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
636716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
636816ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
637047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6374bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
637516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
637616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
637716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
637816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
637916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
638016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
638116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
638216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6383bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
638447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
638816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
638916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
639016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6391bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
639216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
639316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
639416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
639516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6396bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
639716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
639816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
639916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
640016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6401bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
640216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
640347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
640516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
640616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
640716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6408bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
640916ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
641147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
641616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
641716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
641916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
642016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
642347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6428bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
642916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
643016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
643116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
643216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
643316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
643416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
643516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
643616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6437bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
643847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6440bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
644116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
644216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
644316ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
644416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
644516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
644616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
644716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6448bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
644947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
645216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
645316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
645416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6455bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
645616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
645916ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
646016ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
646116ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
646347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
646647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
646947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
647016ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
647116ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6488e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6490bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
649216ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
649616ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
649716ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
649847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6499bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6500bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
650216ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
65037c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6504bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6505bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
650647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6508bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
650947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6510bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6511bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
651247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6513bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
651547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6517bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
651847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
652416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
652516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
652616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
652716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
652947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6533bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
653416ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
653516ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
653616ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
653716ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6538bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
653947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
654016ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
654416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
654516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
654616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6547bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
654816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6549bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
655016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
655116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
655216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6553bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
655416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6555bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
655616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
655716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
655816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6559bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
656016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
656216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
656316ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
656416ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6565bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
656616ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
656847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6573bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
657416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
657516ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6576bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6578bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
657916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
658016ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6581bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
658447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6589bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
659016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
659116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
659216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
659316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6594bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
659547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6597bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
659816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
659916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
660016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
660116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6602bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
660347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
660716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
660816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
660916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6610bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
661116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
661416ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
661616ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
661716ea139d53d867211d3bb0fa859a83de653f687ecristy                    p+=GetPixelChannels(image);
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
661947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
66233faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6629bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
663247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6633bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
663516ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
663616ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
663716ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
663816ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
663916ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
664016ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
664116ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
664216ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
664316ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
664547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
667947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6695bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6696bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
670247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
671447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
672516ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67372b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
67382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
673916ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
67402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
67412b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
67422b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
67432b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
67442b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
67453faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
6746cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
6747cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
6748cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
6749cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
6750cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
6751cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
675216ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
67538640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6755d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6759bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6762d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6766d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
676847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
677047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
677447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
67850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
678616ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
679116ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
679647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
680047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
68130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
681516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
68160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
68210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
68240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
683247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
683316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
683647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
68390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
68410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
684647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
684716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
685247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
686047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
686116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
686547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
687147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
687216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
687447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
687747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
68850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
68880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
68910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
689647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
69020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
69040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6907e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6908e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
69090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
691747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
692047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6922e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
692347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6928e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6940bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
694547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
694716ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
694847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
695147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
695447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
696347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
696647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
698347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
699347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
699647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6998e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6999e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
700047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7002f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7003f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
700447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7005f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7006e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7007e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7008f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7009f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
701047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
701447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
701747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
702025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
702547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
702847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
703147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
703625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7059bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7062bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
707547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
708147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
708947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
709347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
710147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
710447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
710947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
711247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
711547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
712147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
712647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
713147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
713447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
713947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
714447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
715447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
715847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
716547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
716847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
717347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
718147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
718647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
719447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
720147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
720847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
720918b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7210cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
721118b17443128598500357da7bff2f01683cf32890cristy#endif
721247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
724347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7245cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
7246cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
725125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
727016ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
727116ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
727916ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7329cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7336bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
73570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
73580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
73600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
73783b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7379f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
738147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7382bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
738947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
739647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
739947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7405cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
74064383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
742047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
742147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
742247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
742447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7428cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
743047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
743147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
743247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
743347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
743447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
743547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7436cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7437cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7438cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
743947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
744047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
744147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
744247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
744347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
744447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
744547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7446cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
744747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
744947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
745247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7456b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7457b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
745916ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
746116ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
746216ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
746316ea139d53d867211d3bb0fa859a83de653f687ecristy
746416ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
746516ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
746616ea139d53d867211d3bb0fa859a83de653f687ecristy
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
74683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
74793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7480cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7481cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7482e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7483e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
74845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
748539992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
748639992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
74895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
74905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
74915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
74933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
74995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
75005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
75015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7502bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
750658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
750721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
750858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
750958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7510da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7511fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7512d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
75138d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
751439992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7515991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7516991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7517991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
751826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
751926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
752026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7521a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7522e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
752326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
752426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
752526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
752626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
752726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
752826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
752926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7530e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
753126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
753226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
753326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
753426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
75358d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
75360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
75370e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
753882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
75398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7540d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7541d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
754616ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
754716ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
754816ea139d53d867211d3bb0fa859a83de653f687ecristy
7549bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7554cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7557f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
75580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
75595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
75605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
75615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
75625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
75635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
75645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7565bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
75665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
75675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7569bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7574dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7575fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7576f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
75778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
75788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
75798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7580dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7581dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7582dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7583dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7584dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7585dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7587fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
758916ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
759016ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
759116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
759216ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7593b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7595cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
75990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
76005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
76015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
76025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
76035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
76045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
76055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
76065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
76075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
76085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
76095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
76105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
76115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
76125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
76135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
76145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
76155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
76165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7617dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
7618dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
7619dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
7620dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7621da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
7622d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
76238d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
762439992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
7625991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
7626991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
7627991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
7628991d11dd9c33e65872778b81aff1347cd2878154glennrp
76290e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
76300e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
7631a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
7632dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
76330e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
76340e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
76350e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
76360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
76370e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
76380e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
76390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7640dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
76410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
76420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
76430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
76440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
76458d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
76460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
76470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
76480d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
76490d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
76500d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
76510d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
76520d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
76530d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
76540d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   if (ping_exclude_sRGB == MagickFalse)
76550d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
76560d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
76570d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
76580d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
76590d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
76600d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
76610d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
76620d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
76630d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
76640d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
76650d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
76660d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
76670d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
76680d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
76690d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
767016ea139d53d867211d3bb0fa859a83de653f687ecristy               (LocaleCompare(name,"ICM") == 0))
767116ea139d53d867211d3bb0fa859a83de653f687ecristy              {
7672ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
7673ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   icheck;
76740d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7675ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 /* 0: not a known sRGB profile
7676ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 1: HP-Microsoft sRGB v2
7677ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 2: ICC sRGB v4 perceptual
7678ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 3: ICC sRGB v2 perceptual no black-compensation
7679ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  */
76800d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 png_uint_32
7681ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   check_crc[4] = {0, 0xf29e526dUL, 0xbbef7812UL, 0x427ebb21UL},
7682ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   check_len[4] = {0, 3144, 60960, 3052};
76830d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7684ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
7685ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
7686ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   profile_crc;
768729a106ed9ec29e243521b0f2a26c14281de8347fglennrp
7688ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
7689ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
76900d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7691ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
769229a106ed9ec29e243521b0f2a26c14281de8347fglennrp
7693ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 for (icheck=3; icheck > 0; icheck--)
769429a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
7695ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   if (length == check_len[icheck])
7696ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
7697ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7698ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
7699ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
77000d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7701ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     data=GetStringInfoDatum(profile);
7702ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     profile_crc=crc32(0,data,length);
77030d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7704ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7705e54cd4b9aa386137b617b4b7fc66436c70466007glennrp                         "      with crc=%8x",(unsigned int) profile_crc);
7706ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
7707ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     if (profile_crc == check_crc[icheck])
7708ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
7709ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7710ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                            "      It is sRGB.");
7711ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
7712ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                          image->rendering_intent=PerceptualIntent;
7713ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
7714ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
771529a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
77160d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
7717ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 if (icheck == 0)
771829a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7719ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        "    Got a %lu-byte ICC profile",
772029a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
772129a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
77220d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
77230d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
77240d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
77250d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
77260d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
77278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
77288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
77298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
77308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7731fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
7732fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7733fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
7734fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7735fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
7736fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
7737fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7738fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
7739fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
7740fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7741fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
7742fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
774328af3713c9111a471cc868c787760de89236fa3cglennrp
77447e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  if (image->storage_class == PseudoClass &&
77457e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
77467e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png_colortype != 0 &&
77477e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     mng_info->write_png_colortype != 4)))
77487e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
774916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
77507e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
77517e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
77527e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
7753c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
775428af3713c9111a471cc868c787760de89236fa3cglennrp    {
7755c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
7756c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
7757c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
7758c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
7759c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7760c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
7761e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
7762c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
7763c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
776428af3713c9111a471cc868c787760de89236fa3cglennrp    }
7765bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
7766510d06a3f7063e91993e13d546d5685048248074cristy  if (IsRGBColorspace(image->colorspace) == MagickFalse)
776716ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
77680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77693241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
77703241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
77713241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
77723241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
77733241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
777416ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
77753241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7776a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
7777a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
7778a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
7779a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
7780a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7781a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
7782a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7783a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
7784a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
7785a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
7786a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
77878e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
778867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < MAGICKCORE_QUANTUM_DEPTH)
778967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
779016ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
77918e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
77928e58efdecda887b08ef730d68290a61081ef2566glennrp
77938e58efdecda887b08ef730d68290a61081ef2566glennrp       if (image->depth > 8)
77948e58efdecda887b08ef730d68290a61081ef2566glennrp         {
77958e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 16
77968e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 16-bit */
779791d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR16PacketRGBO(image->background_color);
77988e58efdecda887b08ef730d68290a61081ef2566glennrp
77998e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
78008e58efdecda887b08ef730d68290a61081ef2566glennrp           {
780116ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
78028e58efdecda887b08ef730d68290a61081ef2566glennrp
780316ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
78048e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
78058e58efdecda887b08ef730d68290a61081ef2566glennrp
78068e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
78078e58efdecda887b08ef730d68290a61081ef2566glennrp             {
780816ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR16PixelRGBA(r);
780916ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
78108e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7811bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
78128e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
78138e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
78148e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78158e58efdecda887b08ef730d68290a61081ef2566glennrp
78168e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
78178e58efdecda887b08ef730d68290a61081ef2566glennrp           {
78183e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
78198e58efdecda887b08ef730d68290a61081ef2566glennrp             {
782091d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR16PacketRGBO(image->colormap[i]);
78218e58efdecda887b08ef730d68290a61081ef2566glennrp             }
78228e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78238e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 16 */
78248e58efdecda887b08ef730d68290a61081ef2566glennrp         }
78258e58efdecda887b08ef730d68290a61081ef2566glennrp
78268e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 4)
78278e58efdecda887b08ef730d68290a61081ef2566glennrp         {
78288e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 8
78298e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 8-bit */
783091d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR08PacketRGBO(image->background_color);
78318e58efdecda887b08ef730d68290a61081ef2566glennrp
78328e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
78338e58efdecda887b08ef730d68290a61081ef2566glennrp           {
783416ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
78358e58efdecda887b08ef730d68290a61081ef2566glennrp
783616ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
78378e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
78388e58efdecda887b08ef730d68290a61081ef2566glennrp
78398e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
78408e58efdecda887b08ef730d68290a61081ef2566glennrp             {
784116ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR08PixelRGBA(r);
784216ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
78438e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7844bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
78458e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
78468e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
78478e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78488e58efdecda887b08ef730d68290a61081ef2566glennrp
78498e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
78508e58efdecda887b08ef730d68290a61081ef2566glennrp           {
78513e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
78528e58efdecda887b08ef730d68290a61081ef2566glennrp             {
785391d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR08PacketRGBO(image->colormap[i]);
78548e58efdecda887b08ef730d68290a61081ef2566glennrp             }
78558e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78568e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 8 */
78578e58efdecda887b08ef730d68290a61081ef2566glennrp         }
78588e58efdecda887b08ef730d68290a61081ef2566glennrp       else
78598e58efdecda887b08ef730d68290a61081ef2566glennrp         if (image->depth > 2)
78608e58efdecda887b08ef730d68290a61081ef2566glennrp         {
78618e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
786291d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
78638e58efdecda887b08ef730d68290a61081ef2566glennrp
78648e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
78658e58efdecda887b08ef730d68290a61081ef2566glennrp           {
786616ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
78678e58efdecda887b08ef730d68290a61081ef2566glennrp
786816ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
78698e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
78708e58efdecda887b08ef730d68290a61081ef2566glennrp
78718e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
78728e58efdecda887b08ef730d68290a61081ef2566glennrp             {
787316ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
787416ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
78758e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7876bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
78778e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
78788e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
78798e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78808e58efdecda887b08ef730d68290a61081ef2566glennrp
78818e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
78828e58efdecda887b08ef730d68290a61081ef2566glennrp           {
78833e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
78848e58efdecda887b08ef730d68290a61081ef2566glennrp             {
788591d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
78868e58efdecda887b08ef730d68290a61081ef2566glennrp             }
78878e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78888e58efdecda887b08ef730d68290a61081ef2566glennrp         }
78898e58efdecda887b08ef730d68290a61081ef2566glennrp
78908e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
78918e58efdecda887b08ef730d68290a61081ef2566glennrp         {
78928e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
789391d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
78948e58efdecda887b08ef730d68290a61081ef2566glennrp
78958e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
78968e58efdecda887b08ef730d68290a61081ef2566glennrp           {
789716ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
78988e58efdecda887b08ef730d68290a61081ef2566glennrp
789916ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79008e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79018e58efdecda887b08ef730d68290a61081ef2566glennrp
79028e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
79038e58efdecda887b08ef730d68290a61081ef2566glennrp             {
790416ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
790516ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
79068e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7907bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
79088e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
79098e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
79108e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79118e58efdecda887b08ef730d68290a61081ef2566glennrp
79128e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
79138e58efdecda887b08ef730d68290a61081ef2566glennrp           {
79143e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
79158e58efdecda887b08ef730d68290a61081ef2566glennrp             {
791691d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
79178e58efdecda887b08ef730d68290a61081ef2566glennrp             }
79188e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79198e58efdecda887b08ef730d68290a61081ef2566glennrp         }
79208e58efdecda887b08ef730d68290a61081ef2566glennrp       else
79218e58efdecda887b08ef730d68290a61081ef2566glennrp         {
79228e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
792391d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
79248e58efdecda887b08ef730d68290a61081ef2566glennrp
79258e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
79268e58efdecda887b08ef730d68290a61081ef2566glennrp           {
792716ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79288e58efdecda887b08ef730d68290a61081ef2566glennrp
792916ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79308e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79318e58efdecda887b08ef730d68290a61081ef2566glennrp
79328e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
79338e58efdecda887b08ef730d68290a61081ef2566glennrp             {
793416ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
793516ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
79368e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7937bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
79388e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
79398e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
79408e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79418e58efdecda887b08ef730d68290a61081ef2566glennrp
79428e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
79438e58efdecda887b08ef730d68290a61081ef2566glennrp           {
79443e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
79458e58efdecda887b08ef730d68290a61081ef2566glennrp             {
794691d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
79478e58efdecda887b08ef730d68290a61081ef2566glennrp             }
79488e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79498e58efdecda887b08ef730d68290a61081ef2566glennrp         }
7950cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
7951cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
795267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
795367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
795470e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
7955a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
79562b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
79572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
79582b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
79592b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
79608e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
79612b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
79622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
79632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79643faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7965cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
7966cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
7967cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
7968cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
7969cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
7970cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
7971c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
797216ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
79738640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
79748640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
79758640fb5e9b1094f35f8beab436f81661b8a99448glennrp
7976c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp  /* Normally we run this just once, but in the case of writing PNG8
7977e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
7978e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
79798ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
79808ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
79818ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
79828ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
7983c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
798482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
79858ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
798682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
7987d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
798882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
79898ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
7990d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
7991d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp    /* BUILD_PALETTE
7992d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7993d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
7994d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
7995d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7996d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
7997d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
7998d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
7999d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8000d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8001d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
800216ea139d53d867211d3bb0fa859a83de653f687ecristy     * If image->matte is MagickFalse, we ignore the alpha channel
8003d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8004d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8005d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8006d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8007d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8008d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8009d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8010d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8011d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
80123c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8013d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8014d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
80158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
801616ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8017d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8018d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8019d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
80208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
802116ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
802216ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8023d6bf1617e99df0272b231855a933a74e99b6578fglennrp
802416ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
802516ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8026fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8027fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8028d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8029d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8030d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8031d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8032d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8033d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8034d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8035d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8036d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8037d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8038d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8039d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->matte=%.20g",(double) image->matte);
804003812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8041d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
80423c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8043fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
80447ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
80457ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8046d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
80478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
804816ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
80492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8050d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
80517ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8052d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8053d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8054d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8055d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8056d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8057d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
805816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
80597ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
80602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8061d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8062d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8063d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8064d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8065d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8066d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8067d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8068d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8069d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8070d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
807116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8072d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8073d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8074d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
80752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8076d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8077d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
807883c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8079d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
808016ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
808116ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
80827ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
80838d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
80848d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80858d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8086d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
80877ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8088d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8089fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8090fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8091fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
80922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8093d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8094d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8095d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
80967ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
809716ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8098d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
809997fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8100d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8101d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
81024737d521d1d9e5d9a7c55375027ba4befc711046glennrp           if (image->matte == MagickFalse ||
810316ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
81048d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8105d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
81068d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8107d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8108d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
810916ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
811016ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8111d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8112d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8113d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8114d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8115d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
811616ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, opaque+i))
8117d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8118d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8119d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
812016ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8121d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8122d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
812316ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
812416ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8125d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
81268d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
81278d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
812816ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
81298d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8130d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
81318d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8132d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8133d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
813416ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
813516ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
813616ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
813716ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
813816ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
813916ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
814016ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
814116ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
814216ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
8143d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8144d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8145d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8146d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8147d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
814816ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, transparent+i))
8149d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8150d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8151d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8152d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8153d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8154d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8155d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
815616ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8157d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
81588d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
81598d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8160d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8161d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8162d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8163d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8164d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8165d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
816616ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
81698d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8170d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8171d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
817216ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
817316ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
817416ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8175d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8176d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8177d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8178d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8179d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8180d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8181d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
818216ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8183d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8184d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
81858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
818616ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8187d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8188d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
81893c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
81904054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
81914054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8192d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8193d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8194d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8195d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8196c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8197c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8198c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8199c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8200c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8201c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8202c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8203c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8204d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8205d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8206ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8207ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8208ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8209ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8210d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8211d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
821203812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
82138e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8214c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8215c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8216c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8217c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8218c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8219c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8220c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
822103812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8222a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8223a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8224a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8225d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
82262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8227d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
82283241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8229a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
8230a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
8231a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
8232a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
8233a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
8234a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
8235a080bc32a4a8b2ffec83fd836a28753959175363glennrp
8236d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8237d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8238d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8239d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8240d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
82413241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8242d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8243d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8244d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8245d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
82463241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
82478d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
82488d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
82498d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8250fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8251d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8252d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
8253d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_non_bw=MagickFalse;
82543241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8255d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8256d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8257d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8259d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82606185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
826116ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8262d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
82636185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8264e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8265e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8266e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
826716ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
826816ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8269e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8270e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8271e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8272e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8273e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
827416ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8275e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8276e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8277e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8278e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8279e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8280d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8281d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8282d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
82836185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8284d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8285d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8286d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8287d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
82886185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
828916ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
829016ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8291d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8292d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8293e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8294d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
829516ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8296d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8297e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8298d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8299bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8300bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
83014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8302d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8303d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
830416ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8305d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8306bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8307d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8308d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8309d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8310d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8311d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8312d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8313d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8314d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8315d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8316d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8317d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
83183241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8319d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8320d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
83213241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8322d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8323d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8324d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8325d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8326d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8327d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8328c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8329c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8330bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8331d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8332d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8333d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8334d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8335d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8336d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8337d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8338d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8339d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8341d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8342d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8343d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8344d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8345d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8346d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8347d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8348d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8349d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8350d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8351d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8352d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
83533241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8354d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8355d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8356d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8357d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8358d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8359d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8360d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
83616185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8362d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8363d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8364d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8365d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
83662cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8367d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8368d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8369d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8370d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8371d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8372d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
837316ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8374d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
83753faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
83763faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8377d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8378d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8379d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8380d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8381d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8382d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8383d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8384d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8385d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8386bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8387d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8388d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8389d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8390d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8391fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8392fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8393d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8394d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
839516ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83963c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
839716ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8398d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
83993c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8400d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8401d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8402d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
840303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
8404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  if ((image->matte == MagickFalse ||
840516ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
840616ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
840716ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
840816ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
84096185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
841016ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
84126185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
841303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
841416ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8415d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8416d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8420d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8423d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
843116ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
843283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8433d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
843572988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8439d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8441d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
844316ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
84456185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
84466185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
84473c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
84533c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8454d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8455d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
84563c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8457d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
846103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
84656185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
84706185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8473d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8474a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8478a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8479d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
84866185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
848703812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
848803812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8489d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
84903c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8491c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8492c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8493fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8494c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8495c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8496c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8497c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8498c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8499c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8500fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8501c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8502130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8503130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8504130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8505c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8506130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8507c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8508c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8509c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8510fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8511c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8512c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
851316ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8514fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
851516ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8516c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8517fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8518c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8519c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
852016ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
85218ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
852216ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelInfoPixel(image,&image->background_color,r);
852316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
85248ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
85258ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
852616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
852716ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8528c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8529bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8530c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8531c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8532fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8533c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8534c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8535c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
853616ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
853716ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
853816ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
8539c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8540c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8541c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8542c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8543c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8544e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8545e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8546e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8547c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8548d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8549d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8550d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8551d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8552d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8553d337164012450d70d62e71cf4a308a29004f7d57glennrp
8554d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8555d337164012450d70d62e71cf4a308a29004f7d57glennrp
855691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8557d337164012450d70d62e71cf4a308a29004f7d57glennrp
8558d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8559d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8560d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8561d337164012450d70d62e71cf4a308a29004f7d57glennrp
8562d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8563d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8564d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8565d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
856616ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8567d337164012450d70d62e71cf4a308a29004f7d57glennrp
856816ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8569d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
8570d337164012450d70d62e71cf4a308a29004f7d57glennrp
8571d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
8572d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
857316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
857454cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
857516ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8576d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
8577bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8578d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8579d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
8580d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8581d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8582d337164012450d70d62e71cf4a308a29004f7d57glennrp
8583d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
8584d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
8585d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8586d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
8587d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8588d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
85898e58efdecda887b08ef730d68290a61081ef2566glennrp
8590d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
8591d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
859291d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
8593d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8594d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8595d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
8596d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
8597d337164012450d70d62e71cf4a308a29004f7d57glennrp
859882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
859982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
860082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
860182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
860282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
860382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
860482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
860582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
860691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
860782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
860882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
860982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8610e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
861182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
861282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
861382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
861482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
861582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
861616ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
861782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
861816ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
861982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
862082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
862182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
862282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
862316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
862416ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
862516ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
862682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
8627bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
862882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
862982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
863082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
863182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
863282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
863382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
863482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
863582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
863682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
863782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8638e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
863982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
864082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
864191d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
864282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
8643d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8644d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
864582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
8646c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
86478ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
8648c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8649c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
8650c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8651c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
8652c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
86538ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
86548ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
86553faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
86563faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
86573faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
86583faa9a3fb01696daaf976d595f492cb530bffb21glennrp
865991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
8660fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8661c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
8662c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8663e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
8664fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8665c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
8666c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8667c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
8668c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
866916ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
86708d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
867116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8672c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
8673c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8674c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
8675c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
867616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
867754cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
867816ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8679c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
8680bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8681c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8682c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
8683c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8684c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8685c722dd852e8abe407c2846d39662f7ade9c234deglennrp
8686c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
8687c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
8688c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8689c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
8690c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8691e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
8692c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
8693c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
869491d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
8695c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8696c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
8697c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8698c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8699c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
87008ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
87018ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
87028ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
87038ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      /* Take care of special case with 256 colors + 1 transparent
87048ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
87058ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
87068ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
87078ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
87088ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
87098ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
87108ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
87118ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
87128ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
87138ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
8714bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
87158ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
87168ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
87178ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
87188ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
871916ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8720bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
872116ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
87228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
8723bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
87248ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
87258ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
872616ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
872716ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
872816ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
872916ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
87308ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
873116ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
87328ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
873316ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
87348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
8735bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
87368ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
87378ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
8738bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
87398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
87408ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
87418ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
87428ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
87438ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
87448ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
87458ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
87468ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
87478ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
87488ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
87498ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
87508ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
87518ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
87528ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
87538ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
87548ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
8755fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
8756fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
8757fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8758fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
8759fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
8760fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
8761fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
87620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
87630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
87640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
8765d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
87660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
87670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
87680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
87690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
87700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
87710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
87720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
87738d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
8774d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
87750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
87760b206f5daa453dc1035db5890cabc899736dc2d0glennrp
87770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
87780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
8779fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
8780fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
8781fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
87825a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
87835a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
87845a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
8785fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
87865a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
87875a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
8788fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8789fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
8790fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8791fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
8792fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
8793fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8794fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
8795fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
8796fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
879716ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
8798fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
8799fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8800fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
8801fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
8802fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
8803fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
880416ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
8805fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
8806fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8807fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
8808fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
880916ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
881016ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
881116ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
881216ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
881316ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
881416ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
881516ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
8816fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
8817fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8818fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8819fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
8820fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
882116ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
8822fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
8823bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8824fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
8825fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
8826fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
8827fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8828fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
8829fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
883067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
883167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
883267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
8833fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
883467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
883567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
883667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
883767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
8838fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
883967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
884067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
8841fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
8842fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8843bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8844fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
8845fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8846fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
8847fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8848fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
8849fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8850fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
8851fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8852fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
8853fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8854fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
8855fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
8856fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
8857fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
88583c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
88593c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
88603c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
88613c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
8862f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
88633c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
886483c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
88650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
88661273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
886852a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
886952a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
887052a479ca718756af72f96e127f8256499ab68f76glennrp    {
887116ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
887216ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
887316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
887415e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
887516ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
887652a479ca718756af72f96e127f8256499ab68f76glennrp#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
887752a479ca718756af72f96e127f8256499ab68f76glennrp      UnlockSemaphoreInfo(ping_semaphore);
887852a479ca718756af72f96e127f8256499ab68f76glennrp#endif
887952a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
888052a479ca718756af72f96e127f8256499ab68f76glennrp    }
888152a479ca718756af72f96e127f8256499ab68f76glennrp
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
888616ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
888716ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
888816ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
8889cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
8890cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
88910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
889316ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
8894cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
88950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
88990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
89010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
89033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
89063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
8909cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
89123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
89143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
89153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
89173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
89183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8922cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
892416ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
892516ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
892616ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
892716ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
89362b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
89412b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89442b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
89462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89474e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
89484e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
89492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
89520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
89550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
89590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
89620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
89650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8969e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8971e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8973e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89758640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89778640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89798640fb5e9b1094f35f8beab436f81661b8a99448glennrp
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
89815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
8982dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
898326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
898526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
898626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
898716ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
8991dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8992dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8996dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8997823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
899816ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
8999823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
900016ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9002dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9005dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
900616ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
900716ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9009991d11dd9c33e65872778b81aff1347cd2878154glennrp
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9012dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
901316ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
901416ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9016991d11dd9c33e65872778b81aff1347cd2878154glennrp
9017823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9018823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9019823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9020823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9021823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9022991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
902426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9026a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
902726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
902826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9029a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9031a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9032a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9033a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9034a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9035a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9036a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
90370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9038a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9039a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
90400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9041a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9042a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
90430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9044a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9045a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
90460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9047a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9048a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
90490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9050a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9051a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
90520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9053a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9054a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9055c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9056c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
90570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
90580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
90603b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
90613b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90623b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9063c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9064c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9065c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
90663b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
90673b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90683b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
90693b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
90700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
907226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
90790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90801273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
90813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9083fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
90840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
90850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
90878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
90888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
90890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
90910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
90920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
90930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
90940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
90960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9098f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
90990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
91010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
91020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
91030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
91040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
91050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
91060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
910767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
91080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
910967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
911067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
911167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
91120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
91152b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
91168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
91178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
91188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
91195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
912058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
91218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
91220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
91230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
91240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
91250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
91268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
91298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
91300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91322cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
91338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
91340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
91360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
91370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
91398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
91408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
91410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91421273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
91434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
91441273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
91451273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
91461273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
91471273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
91484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
91494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
91504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
91510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9153c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9154c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9155c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9156c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9157c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9158c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9159c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
91604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
91620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91637e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  else if (mng_info->write_png24 || mng_info->write_png_colortype == 3)
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
91665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91697e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  else if (mng_info->write_png32 || mng_info->write_png_colortype == 7)
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
91725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
91780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
91820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
91845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
91862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
91888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
91897c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
91907c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
91917c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91927c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91957c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91993c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
92000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9201d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
92028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
92030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9204d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
92065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
92090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9210d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
92125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
92150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92165aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
92175aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
92185aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
92195aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
92207c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
92217c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
92227c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
92245aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
92258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
92265aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
92275aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
92285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
92295aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
92305aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
92310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92320b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
92335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
92345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
92355aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
92365aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
92378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
92385aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
92395aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
92405aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
92415aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
92425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
92435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
92445aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
92458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
92460b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
92475aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
92485aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
92495aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
92505aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
92515aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
92520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
92535aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
92550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
925726c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92588640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
925926c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
92605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
92610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
92620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
92630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
92640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
92650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
92660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9268d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9269d6bf1617e99df0272b231855a933a74e99b6578fglennrp
92705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
92728d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp          if (image->matte == MagickFalse && ping_have_non_bw == MagickFalse)
92738d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
92758640fb5e9b1094f35f8beab436f81661b8a99448glennrp
92765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
927835ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
92795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
92800f111984738842d27d04aed2a3f823d82a943506glennrp
92810f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
92820f111984738842d27d04aed2a3f823d82a943506glennrp           {
92830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
928416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,
92850f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
9286c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                "image has 0 colors", "`%s'","");
92870f111984738842d27d04aed2a3f823d82a943506glennrp           }
92880f111984738842d27d04aed2a3f823d82a943506glennrp
928935ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
92905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9291d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
92923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9293d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9294d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9295d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9296d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
92970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9298d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9299d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9300d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
93010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9302d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9303d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
93065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
93072b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9311e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
93120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9314e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
93150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9317e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
93180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93203c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
93218640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
93228640fb5e9b1094f35f8beab436f81661b8a99448glennrp
93238640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9324e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
932758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
93304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
93317c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
93327c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
93337c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
93342b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93357c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
93367c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
93377c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
93382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
93404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
93424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
93434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
93444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
93454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
93464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9347a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
93484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
93497c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
93507c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
93517c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
93524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
93530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
93554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
93564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9357bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
93600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
93624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
93630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
93654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
93660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
93684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
93690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
93714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
93720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
93744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
93750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
93774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
93780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
93804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
93810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
938316ea139d53d867211d3bb0fa859a83de653f687ecristy                (ScaleQuantumToShort(GetPixelInfoIntensity(
93844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
93850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
93870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
93894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
93900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
93924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
93934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9394fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9395fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9396fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9397fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9398fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
93994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
94002b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
94024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
94037c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
94047c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
94050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
94074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
94084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
94094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
94104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
94114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
94124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
94134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
94144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
94154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
94164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
94195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
94205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
94215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
94225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94268640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
94280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94292e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
94310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
943239992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
94348d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
94358d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
943735ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
94380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
94409c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
94410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94427c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
94445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
94454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
94474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
94484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
94494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
94504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
94524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
94534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
94544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
94560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
94590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9460136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9461d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9462f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
94630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
94655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
94660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
94695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
94705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
94745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
94750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
947635ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
94785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
94812b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
94830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
94871a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9493bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
94963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
94993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
95044bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
95072b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
95099c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
95100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
95129c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
95130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
95159c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95182b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
95203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
95230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
95253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
952617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
952717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
95335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
95340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
953558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
95379c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
95380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95393b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
95409c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95419c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9546bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
95473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
95483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
95493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
95520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95533b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
95543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
955598156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
9556f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
95570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
955839992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
9562d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9564befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
9565befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
9566befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
95675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
9568befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
95690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
957016ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
95715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
95750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
957658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
95770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
95780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
9579d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
9580d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
95810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
95823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9583d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
9584d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
95853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
95870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
95880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9589d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
95900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
9591c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
9592c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
9593c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9594c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
9595c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
9596d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
9597d6bf1617e99df0272b231855a933a74e99b6578fglennrp
9598d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
9599d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
960016ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_alpha[i]= (png_byte)
960116ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
9602d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
96030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
96040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
96070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
96093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9610c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
96113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
96123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
96130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
96153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
96174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
96184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
96204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
96214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
96224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
96234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
96244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
96255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
96265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
96275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
96285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
96294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
96304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
96314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
96324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
96344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
96354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
96364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
96374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96414383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
96424383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
96432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
96475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
96483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
96493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
96513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
965335ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
965435ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
965535ef824baa82511126ff0072ae30eee0da9c05a3cristy
965622ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
965926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
96603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
966116ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
966216ea139d53d867211d3bb0fa859a83de653f687ecristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(
966316ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
966416ea139d53d867211d3bb0fa859a83de653f687ecristy
96653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
96668f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
966716ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
966816ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
966916ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
967016ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
96713b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
9672991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
967326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
96743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96753e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
96763e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96773e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
96783e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
96793e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
96809be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
96813e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
96823e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
96833e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
96843e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96853e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
96863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
968717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
968826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
968926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
96901273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
969117a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
969217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
969317a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
969417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
969517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
969617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
969717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
9698a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
9699a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
970017a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
970117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
970217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
970317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
97043b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
97050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
97060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
97080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
9709a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
971013d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
9711a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
97120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
97133b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
97143b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
97150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
97160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
97180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
97190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
97200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
97210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
9722a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
972317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
9724d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
97253c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
97263b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
97273b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97283b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
97293c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
97303c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
973117a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
973226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
973317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
97343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
97393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
97420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
97440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
97470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
97480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
97500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
97540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97554054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
97564054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
975710d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
975810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
975910d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
976010d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
976110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
976210d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
976310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
976410d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0: Use Z_HUFFMAN_ONLY strategy with the
976510d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
976610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
976710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
976810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
976910d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
977010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
977110d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
977210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
977310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
977410d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
977510d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
977610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
977710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
977810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
977910d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
978010d739ef54404090a55cb8977fc51f85cafa81a5glennrp             a MNG, othewise "none".  Did not work in IM-6.7.0-9
978110d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
978210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
978310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        8:   Z_RLE strategy, all filters
97841868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
978510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
978610d739ef54404090a55cb8977fc51f85cafa81a5glennrp        9:   Z_RLE strategy, no PNG filters
97871868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
978810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
978910d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
979010d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
979116ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
979216ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
979310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
979410d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
979510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
97963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
97980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97991868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
98001868258559ddf946fa73ef72dd43507b32623705glennrp    {
98011868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
98021868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
98031868258559ddf946fa73ef72dd43507b32623705glennrp    }
98041868258559ddf946fa73ef72dd43507b32623705glennrp
98051868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
98063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
98083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
98093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9810bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
98110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98121868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
98131868258559ddf946fa73ef72dd43507b32623705glennrp    }
98140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98151868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
98161868258559ddf946fa73ef72dd43507b32623705glennrp    {
98171868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
98181868258559ddf946fa73ef72dd43507b32623705glennrp            mng_info->write_png_compression_strategy=Z_RLE;
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98211868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
98221868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
98231868258559ddf946fa73ef72dd43507b32623705glennrp
98241868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
98253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98261868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98281868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
98291868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
98300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98311868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
98321868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98331868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
98341868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
98350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98361868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98371868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98394054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
984010d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98411868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
98424054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
98434054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
98441868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98451868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
98461868258559ddf946fa73ef72dd43507b32623705glennrp        else
98471868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98481868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
98491868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98521868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
98531868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
98540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98551868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
98561868258559ddf946fa73ef72dd43507b32623705glennrp    {
98571868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
98581868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
98591868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
98601868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
98611868258559ddf946fa73ef72dd43507b32623705glennrp      else
98621868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
98631868258559ddf946fa73ef72dd43507b32623705glennrp     }
98644054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
98651868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
98661868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
986710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
98681868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
98691868258559ddf946fa73ef72dd43507b32623705glennrp    {
98701868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
98711868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
98721868258559ddf946fa73ef72dd43507b32623705glennrp      {
98731868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
98741868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
98751868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
98761868258559ddf946fa73ef72dd43507b32623705glennrp      }
98771868258559ddf946fa73ef72dd43507b32623705glennrp#endif
98784054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
98791868258559ddf946fa73ef72dd43507b32623705glennrp    }
98800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98811868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
98821868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
98830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98841868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
98851868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
98861868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
98870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98881868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
98891868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
98901868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
98912b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98920d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
98930d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
98940d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy     (image->rendering_intent == UndefinedIntent))
98950d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
98960d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
98970d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
98980d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
9899c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
9900c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
9901c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
99023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9903c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
99040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9905c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
9906c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
9907c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
9908c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
9909c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
991026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
9911c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
9912c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
9913c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
991416ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
9915e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
9916c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
9917e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
9918e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
9919e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
9920c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
9921c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
992226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
99230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9924c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9926c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
9927c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
9928cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
9929c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
9930c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
9931c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
9932c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
9933c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
99340b206f5daa453dc1035db5890cabc899736dc2d0glennrp
9935c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
9936c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9937c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
99380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9939c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
9940c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
99410d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
994926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
995026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
995126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
995226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
995326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
995426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
995526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
995626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
99570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
995826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
9959cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
9960cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
996126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
996326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
99645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99672cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
99682cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
996926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
997026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
99803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
998326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
99842b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
998526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
998726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
998826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
998926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
999026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
999126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
999226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
999326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
999426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
999526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
999626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
999726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
999826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
999926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1000026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1000126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1000226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1000326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1000426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1000526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1000626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1000726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1000826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1000926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1001026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1001126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1001226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
100133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10014dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
100155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100205d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10022d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
100258d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
100263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
100275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
100282b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
100295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
100305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
100320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
100348d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
100355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
100363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100380e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
100390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
100405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
100413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
100425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10043991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
100440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
100453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
100473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
100480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
100490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
100500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
100520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
100530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100575d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy                  "  Defined png:bit-depth=%u, Computed depth=%u",
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
100595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
100610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
100623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100655d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy                  "  Defined png:color-type=%u, Computed color type=%u",
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
100675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
100700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
100713bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
100725d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy        "Cannot write image with defined png:bit-depth or png:color-type.");
100733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1007558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (image_matte != MagickFalse && image->matte == MagickFalse)
100763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
1007916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageAlpha(image,OpaqueAlpha,exception);
100800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10081b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
10082b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10083b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
100843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100860e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10087e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
10088991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
10089c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
10090991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
10091c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
10092c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10093c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
10094c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
10095e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
10096e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
100983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
101025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
101035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
101045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
101055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
1010639992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
1010739992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
10108f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
101090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101103b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
1011139992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
101128640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
101130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
10114d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
101150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10116d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10117d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
101180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
101190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
101200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
10121d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
101220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
101230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
101240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10125d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
101260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
101270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
101280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
101290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
101300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
1013139992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
1013239992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
1013339992b4dd9b12ef752d55b8e402c069698851f72glennrp
1013426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1013526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1013626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10137c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1013826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
10139c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging)
10140c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10141c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10142c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10143c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10144c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10145c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10146c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10147c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10148c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10149c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10150c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10151c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10152c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10153c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1015426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10155991d11dd9c33e65872778b81aff1347cd2878154glennrp
1015626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10157dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1015826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1015926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1016026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1016126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1016226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1016326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10164823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
10165823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
10166823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10167823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10168823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10169823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10170823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10171823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10172823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10173823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10174823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10175823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10176823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10177823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10178823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1017926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10180dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10181dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10182dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
101834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10184dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1018526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1018626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1018726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1018826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10189dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1019026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1019126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1019226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1019326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1019426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10195dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10196dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10197dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10198da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10199da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1020016ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10201da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10202da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10203da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10204da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10205da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10206da8f3a7bfddac2680a3069a490db541e7944edafglennrp
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10208991d11dd9c33e65872778b81aff1347cd2878154glennrp
1020939992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10210991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
102113b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
102120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
102130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
102150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10216991d11dd9c33e65872778b81aff1347cd2878154glennrp
102170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
102180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
102190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
102200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
102210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10222991d11dd9c33e65872778b81aff1347cd2878154glennrp
102230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
102240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
102250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
102260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
102270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
102280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
102290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102303b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
102310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
102320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10233c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
102340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
102350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
102360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
102370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
102380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
102390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10240991d11dd9c33e65872778b81aff1347cd2878154glennrp
102413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10242cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10243da8f3a7bfddac2680a3069a490db541e7944edafglennrp
102443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10245991d11dd9c33e65872778b81aff1347cd2878154glennrp
102463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10247cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
102483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1024926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
102503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
102524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1025326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1025426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1025526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1025626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1025726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1025826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1025903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1026026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1026126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1026226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1026326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1026426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1026526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
102663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
102699c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
102703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
102719c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
102723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
102733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
102743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
102763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
102773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
102783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10280b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10281b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
102827202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
102833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10284b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
102853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10286b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
102870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10288b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10289b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10290b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
102910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10292b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
102933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10294b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
102950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10296b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10297b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
102983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102993b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
103003b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
103013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10302b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10303b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
103040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10305b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10306e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
103073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10308cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
10309cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
103100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10311cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
103123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
103130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
103153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
103163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
103175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
103183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
103203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
103213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
103223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
103233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
103243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
103253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
103263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
103283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
10329cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
10330cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
103313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
10332cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
103333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1033416ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
1033516ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
1033616ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
1033716ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
103383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
103393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10340ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10341ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10342ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
103433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
103443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
103453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
103468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
103473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
103488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
103498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
103503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
103518d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
103528d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
103533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1035516ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
103563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
103570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
103593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
103603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
103613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
103623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
103633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10364bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
103653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10366d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
103673b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103683b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10369a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1037016ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
103710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1037216ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
103733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
103740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
103763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1037716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1037816ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
103793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
103803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
103813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
103823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
103833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10384bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10385cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
103863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
103873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
103883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
103890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
103913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1039216ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1039316ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
103943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
103950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10397bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10398cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
103993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
104000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104013b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10402b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10403b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
104040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10405cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
104063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
104073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
104083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
104093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
104103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
104113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
104123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
104133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
104143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
104150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
104173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
104180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
104193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
1042058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
104215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
104228d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
104233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1042416ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
104258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
104260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
104283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
104298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10430bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
104313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1043216ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
104332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1043416ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
104353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
104362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
104383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
104398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1044016ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1044116ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
104422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1044416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1044516ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
104462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
104488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
104503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
104512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10453b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
104543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10455b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
104572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1045816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1045916ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
10460b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
104612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104623b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10463b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
104652cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10466cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
104673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
104682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
104708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
104718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
104728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
104738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
104748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
104758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
104768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
104770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
104793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1048016ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
104818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
104820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
104843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
104858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
104868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
104878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
104888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
104898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10490b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
104918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
1049216ea139d53d867211d3bb0fa859a83de653f687ecristy                   exception);
104932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1049416ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
104958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
104962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
104988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
104998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1050016ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1050116ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
105022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1050416ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1050516ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
105068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
105072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
105098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1051016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10511cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1051216ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
105132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
105158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
105178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
105182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1052016ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1052116ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
105222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1052416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1052516ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
105262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105273b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10528b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
105302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10531cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
10532b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
105338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
105342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
105368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
105378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
105388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
105398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
105408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
105418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
105428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
105438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
105448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
105462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
105488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
105498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
105502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
105528640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
105538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
105548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
105562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1055716ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
105582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1055916ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
105608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
105612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1056344757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
105644bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
105654bf89731a90c6e03598950223e19e7be7b95d630glennrp
1056616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1056716ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1056844757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
105692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
105718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
105728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
105738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
105752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1057616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10577cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1057816ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
105798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
105802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
105828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1058316ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1058416ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
105852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105865eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
105875eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
105885eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105891a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
105905eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
105915eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105925eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
105935eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
105945eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
105958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
10596cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
105978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
105988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
105992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
106018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
106028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
106038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
106048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
106058640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
106098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10610b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
10611b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10616b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
106170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10619e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
106200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10622e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
106230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106275d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
106320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106365d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
106410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10646a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10648823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
106493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1065026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1065126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1065226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1065326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1065426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1065526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
106562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1065716ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
10658a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10659a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      /* Don't write any "png:" properties; those are just for "identify" */
10660a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(property,"png:",4) != 0 &&
10661a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10662a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
10663a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
10664823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
10665a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
10666a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10667a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
10668a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
10669a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1067026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
10671c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
10672c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
10673c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
10674c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
10675c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
10676c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
106772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10678c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
10679c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
106802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10681c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
10682c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
106832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10684c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1068526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
10686c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
10687c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
10688c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
10689c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1069026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
106912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10692c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
10693c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
10694c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10695c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
10696c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
10697c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10698c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "    keyword: %s",text[0].key);
10699c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
10700c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
10701c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
10702c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
10703c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1070426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1070526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1070626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
10710cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
107150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
107170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
107215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
107225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
107243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
107303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1073203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
107353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
107435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
107465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
1075816ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) ThrowMagickException(exception,GetMagickModule(),
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
10760c70af4ac292f8db9a1ab488318912894d412cb8cglennrp       "`%s'",image->filename);
107610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10768cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
10771cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1077416ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1077516ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1077616ea139d53d867211d3bb0fa859a83de653f687ecristy
1077716ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1077816ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1077916ea139d53d867211d3bb0fa859a83de653f687ecristy
10780b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
10781b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
10782b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
10783b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1078416ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
10785b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
107890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1081216ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1081316ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1082116ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1082216ea139d53d867211d3bb0fa859a83de653f687ecristy%
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
108295d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108315a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
108325a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
108355a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
108365a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
10837e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
10838130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
10839130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
10840130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
10841e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
10842e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
10843e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
108445a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
108455a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
108475a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
108485a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
108495a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
108535a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
108545a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
108555a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
108565a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
108575a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
108603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
108620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
108635a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
108645a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
10869bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
10870bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
10871bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
108773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
108883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108895a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
108905a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
108915a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
108925a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
108933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
108965a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1089716ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
109053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
10912bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
10913bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
109173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
10918bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10920bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109223241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
109230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
10924d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
109250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
109260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
109270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
10928cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
109290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
10930d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
10931d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
109325d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
10933d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
10934d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
10935d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
10936d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
109370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
109403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1094116ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
109433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1094421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1094521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1094621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1095621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
109575c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
109585c7cf4e469a4dad7e277783749155932252c52dfglennrp
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
109613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
109643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
109663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10967fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
109703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
109713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1097273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
109730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
109753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
109760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
109793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
10982a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
109843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
109883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
109903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10991b381a2618e8bb9e1e76299676711d0ec1063feabglennrp  value=GetImageOption(image_info,"png:format");
10992b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
10993b381a2618e8bb9e1e76299676711d0ec1063feabglennrp  if (value != (char *) NULL)
10994b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
10995b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
10996b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
10997b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
10998b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickFalse;
10999b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickFalse;
11000b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11001b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11002b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11003b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
11004b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickFalse;
11005b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11006b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickFalse;
11007b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11008b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11009b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11010b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
11011b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickFalse;
11012b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickFalse;
11013b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11014b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11015b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    }
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110189c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
110199c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
110209c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110259c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
110269c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
110279c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
110280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110299c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
1103016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
110310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110329c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1103316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
110340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1103516ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110409c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
110419c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
110429c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
110430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110449c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
1104516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
110460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110479c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1104816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
110490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1105016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
110513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
110548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
110553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
110589c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
110590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
110619c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
110620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
110649c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
110650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
110679c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
110680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
110709c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
110710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11072bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1107316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11074bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11075bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11076bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11077bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
110799c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11080bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
110840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
110899c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
110900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1109116ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1109216ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1109316ea139d53d867211d3bb0fa859a83de653f687ecristy
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
110959c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
110960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
110989c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
110990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
111019c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
111020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
111049c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
111050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11106bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1110716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11108bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11109bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11110bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11111bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
111139c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11114d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
111180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
111190dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
111200e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
111210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
111225d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
111230e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
111240e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
111250e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
111260e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
111270e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
111280e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
111290e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
111305d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
111315d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
111320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
111330dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
111340dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
111350dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11136aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11137aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11138aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
111390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
111400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
111410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
111420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
111430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
111440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
111450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
111460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
111470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
111480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
111490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
111500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
111510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11152104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
111530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
111540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1115526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1115626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11157a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1115826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1115926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1116026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1116126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1116226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1116326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1116426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1116526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11166a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1116726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1116826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1116926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1117026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
111718d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
111728d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
111738d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  value=GetImageArtifact(image,"png:preserve-colormap");
111748d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
111758d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     value=GetImageOption(image_info,"png:preserve-colormap");
111768d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
111778d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
111788d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
111791868258559ddf946fa73ef72dd43507b32623705glennrp  /* Thes compression-level, compression-strategy, and compression-filter
111801868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
111811868258559ddf946fa73ef72dd43507b32623705glennrp   */
111821868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-level");
111831868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
111841868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-level");
111851868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
111861868258559ddf946fa73ef72dd43507b32623705glennrp  {
111871868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
111881868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
111891868258559ddf946fa73ef72dd43507b32623705glennrp       */
111901868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
111911868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
111921868258559ddf946fa73ef72dd43507b32623705glennrp
111930ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
111941868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
111951868258559ddf946fa73ef72dd43507b32623705glennrp
111961868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
111971868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
111981868258559ddf946fa73ef72dd43507b32623705glennrp
111991868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
112001868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
112011868258559ddf946fa73ef72dd43507b32623705glennrp
112021868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
112031868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
112041868258559ddf946fa73ef72dd43507b32623705glennrp
112051868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
112061868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
112071868258559ddf946fa73ef72dd43507b32623705glennrp
112081868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
112091868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
112101868258559ddf946fa73ef72dd43507b32623705glennrp
112111868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
112121868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
112131868258559ddf946fa73ef72dd43507b32623705glennrp
112141868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
112151868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
112161868258559ddf946fa73ef72dd43507b32623705glennrp
112171868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
112181868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
112191868258559ddf946fa73ef72dd43507b32623705glennrp
112201868258559ddf946fa73ef72dd43507b32623705glennrp      else
1122116ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
112221868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
112231868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
112241868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
112251868258559ddf946fa73ef72dd43507b32623705glennrp    }
112261868258559ddf946fa73ef72dd43507b32623705glennrp
112271868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-strategy");
112281868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
112291868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-strategy");
112301868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
112311868258559ddf946fa73ef72dd43507b32623705glennrp  {
112321868258559ddf946fa73ef72dd43507b32623705glennrp
112331868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
112341868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
112351868258559ddf946fa73ef72dd43507b32623705glennrp
112361868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
112371868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
112381868258559ddf946fa73ef72dd43507b32623705glennrp
112391868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
112401868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
112411868258559ddf946fa73ef72dd43507b32623705glennrp
112421868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1124398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
112441868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1124598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1124698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1124798c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
112481868258559ddf946fa73ef72dd43507b32623705glennrp
112491868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1125098c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
112511868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1125298c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1125398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1125498c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
112551868258559ddf946fa73ef72dd43507b32623705glennrp
112561868258559ddf946fa73ef72dd43507b32623705glennrp      else
1125716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
112581868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
112591868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
112601868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
112611868258559ddf946fa73ef72dd43507b32623705glennrp    }
112621868258559ddf946fa73ef72dd43507b32623705glennrp
112631868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-filter");
112641868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
112651868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-filter");
112661868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
112671868258559ddf946fa73ef72dd43507b32623705glennrp  {
112681868258559ddf946fa73ef72dd43507b32623705glennrp
112691868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
112701868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
112711868258559ddf946fa73ef72dd43507b32623705glennrp       *
112721868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
112731868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
112741868258559ddf946fa73ef72dd43507b32623705glennrp       */
112751868258559ddf946fa73ef72dd43507b32623705glennrp
112761868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
112771868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
112781868258559ddf946fa73ef72dd43507b32623705glennrp
112791868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"1") == 0)
112801868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
112811868258559ddf946fa73ef72dd43507b32623705glennrp
112821868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
112831868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
112841868258559ddf946fa73ef72dd43507b32623705glennrp
112851868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
112861868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
112871868258559ddf946fa73ef72dd43507b32623705glennrp
112881868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
112891868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
112901868258559ddf946fa73ef72dd43507b32623705glennrp
112911868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
112921868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
112931868258559ddf946fa73ef72dd43507b32623705glennrp
112941868258559ddf946fa73ef72dd43507b32623705glennrp      else
1129516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
112961868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
112971868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
112981868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
112991868258559ddf946fa73ef72dd43507b32623705glennrp    }
113001868258559ddf946fa73ef72dd43507b32623705glennrp
1130103812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1130203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
113035c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
113045c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
113055c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11306acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
113075c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
11308acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11309acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11310acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
11311acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
113125c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11313acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
113145c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
1131526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11316acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11317acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
11318acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11319acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1132003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1132103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1132226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1132303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1132403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1132526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1132603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1132726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1132803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
113292cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
113302cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
113312cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113322cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
113332cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
113342cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113352cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
113362cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1133703812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1133803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1133903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1134003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1134103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1134203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1134303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1134403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1134503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1134603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
11347a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
1134803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1134903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1135003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1135103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1135203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1135303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1135403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1135503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
11356a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1135703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1135803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1135903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1136003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1136103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
113622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1136303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1136403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1136503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1136603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
11367a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
1136803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1136903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1137003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1137103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1137203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1137303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1137403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1137503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
11376a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1137703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1137803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1137903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1138003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
113812cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1138203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1138303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
113842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1138503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1138603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
113872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11388a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11389a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
11390a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1139103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1139203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
113932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1139403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1139503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
113962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1139703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1139803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
113992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1140003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1140103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1140203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1140303812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
114042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1140503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1140603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
114072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1140803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1140903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
114102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1141103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1141203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
114132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11414a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11415a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
114162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1141703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1141803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
114192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11420a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11421a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
11422a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1142303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1142403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
114252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1142603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1142703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
114282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1142903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1143003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
114312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1143203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11433ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1143426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1143526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
114365c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
114375c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
114385c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11439acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
114405c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
11441acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11442acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11443acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
11444acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
114455c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11446acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
114475c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
1144826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11449acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11450acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
11451acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11452acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1145303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1145403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1145503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1145603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1145726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1145803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1145926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1146003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
114612cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
114622cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
114632cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
114642cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
114652cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
114662cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
114672cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
114682cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1146903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1147003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1147103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1147203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1147303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1147403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1147503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1147603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1147703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
11478a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickFalse;
1147903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1148003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1148103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1148203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1148303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1148403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1148503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1148603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
11487a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1148803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1148903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1149003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1149103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1149203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
114932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1149403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1149503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1149603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1149703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
11498a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickTrue;
1149903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1150003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1150103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1150203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1150303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1150403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1150503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1150603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
11507a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1150803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1150903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1151003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1151103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
115122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1151303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1151403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
115152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1151603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1151703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
115182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11519a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11520a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
11521a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1152203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1152303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
115242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1152503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1152603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
115272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1152803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1152903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
115302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1153203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1153303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1153403812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
115352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1153703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
115382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1154003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
115412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1154203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1154303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
115442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11545a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11546a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
115472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1154803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1154903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
115502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11551a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11552a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
11553a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1155403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1155503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
115562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1155703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1155803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
115592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1156003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1156103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
115622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1156303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11564ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1156526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1156626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1156703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1156826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1156926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
115705d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1157126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1157226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1157326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1157426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1157526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1157626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
11577a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
11578a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11579a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1158026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1158126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1158226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1158326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1158426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1158526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1158626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1158726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1158826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1158926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1159026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1159126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1159226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1159326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1159426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1159526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1159626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1159726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1159826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1159926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1160026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1160126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1160226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1160326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1160426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1160526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
11606a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
11607a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11608a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1160926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1161026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1161126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1161226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1161326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1161426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1161526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1161626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1161726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1161826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1161926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11620b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
116213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1162216ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
116233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
116250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
116273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
116280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
116303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
116313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
116333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
116353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1163616ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
116373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
116383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
116393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
116403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
116423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
116433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1164503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
116463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
116473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
116493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
116503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
116523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
116533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
116543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
116553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
116573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
116583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
116593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
116603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
116613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11662bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1166359575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
116643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
116653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
11667fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
116683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
116703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
116713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
116723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
116743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
1167559575fa5c228308a41d7f5028390be2083aaaf6dglennrp     image_info->type==TrueColorMatteType || image->matte != MagickFalse;
116763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1167759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1167859575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1167959575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1168059575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1168159575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1168259575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1168359575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1168459575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1168559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
116863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
116883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
116900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
116923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1169416ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
116950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
116970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
116993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
117000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
117023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
117033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
117040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1170516ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
117063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
117073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
117083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
117093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
117108f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1171116ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1171216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
117133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
117143b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy      (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
117153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
117163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1171759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1171859575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1171959575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1172059575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1172159575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1172259575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
117233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
117253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
117273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
1172816ea139d53d867211d3bb0fa859a83de653f687ecristy    TrueColorType && ImageIsGray(image,exception))
117293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
117303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1173159575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1173259575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1173359575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1173459575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1173559575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1173659575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
1173759575fa5c228308a41d7f5028390be2083aaaf6dglennrp        if (transparent)
1173859575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1173959575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1174059575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1174159575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1174259575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1174359575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1174459575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1174559575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1174659575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1174759575fa5c228308a41d7f5028390be2083aaaf6dglennrp
117483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
117493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
117503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
117513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
117523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
117533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
117543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1175516ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
117563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1175716ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
117583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
117593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
117603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
117613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
117623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
117643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
117653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
117663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11767cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
11768cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
11769cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
117703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1177116ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
117723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1177416ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
117753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
117763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
117773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
117783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
117793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1178016ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
117813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1178316ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
117843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
117863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
117873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
117883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
117893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
117903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
117913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1179216ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
117933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
117940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
117963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11797e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
11798e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
117993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
118013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
118023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
118033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
118043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
118053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
118083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
118093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1181003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
118114e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
118124e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
118133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
118143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
118153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
118163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
118173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
118183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
118193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
118203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
118213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
118223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
118233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
118243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11826f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
118270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11829f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
118300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
118330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
118360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
118390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
118420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
118450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
118480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
118510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
118543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
11857cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
118583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
118603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
118613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
118623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
118643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
118653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
118663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
118673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
118683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
118703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
118713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
118723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
118733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11874bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
118753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
118763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
118783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
118793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
118803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
11881bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
118823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1188303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
118843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
118853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
118863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
118873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
118883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
118893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
118903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
118913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
118923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
118933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
118943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
118953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
118963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
118983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
119003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
119013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
119023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
119033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1190403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
119050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
11907e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
11908cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
11909e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
119100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
11912e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
11913cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
11914e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
119150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
119173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
119183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
119203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
119213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
119223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
119233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
119243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
119253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
119263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
119273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1192803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1192935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
119303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
119313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
119323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
119353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
119363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
119373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
119383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
119393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
119413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
119423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
119433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
119443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1194503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
119463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1194735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1194835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
119493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1195035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1195135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
119523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1195335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1195435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
119553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1195635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1195735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
119583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
119593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
119603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1196316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
119643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
119653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
119663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
119673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
119683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
119693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1197003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
119713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
119723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1197335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1197416ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
119750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1197635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1197716ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
119780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
119803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
119833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
119843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
119853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1198635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1198716ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
119880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1198935ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1199016ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
119910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
119933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
119940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
119963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1199716ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1199816ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
119993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
120003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
120013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
120023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
120033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
120043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
120073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
120093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
120103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
120113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
120123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1201303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12014bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12015bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
120163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
120173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
120183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
120193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
120213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
120233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1202403812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
120253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
120263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
120273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
120283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
120293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
120303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
120343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
120363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12037bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
120383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
120393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12040bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
120413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
120423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
120443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
120453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12046e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12047f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
120483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
120503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
120513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12052bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
120533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
120543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
120553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
120560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
120583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
120593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12060bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1206103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
120623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
120633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
120643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
120653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
120660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
120683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
120693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
120703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12071e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12072e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
120733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
120743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
120753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
120763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
120773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
120783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
120793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
120803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
120813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12082e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12083bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
120843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1208503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
120863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
120873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
120883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
120893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
120903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
120913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
120923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
120933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
120963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
120973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
120993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
121003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
121013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
121023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
121053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
121063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1210716ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
121083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
121093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
121103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
121113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
121133b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
121143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
121153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1211716ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
121183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12121e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12122e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
121233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
121253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
121260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1212759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1212859575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
121293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
121303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
121310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
121343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
121350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1213616ea139d53d867211d3bb0fa859a83de653f687ecristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,exception);
121370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12141e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12142e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
121433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12145e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
121463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
121470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12149bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1215103812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
121523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
121533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
121543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
121573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
121583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
121593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
121603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12162cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
121633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
121653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
121663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1216703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
121683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
121693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
121703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
121733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
121740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
121763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
121773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
121803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
121823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
121833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
121843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
121853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
121863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
121873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
121883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
121903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
121923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
121933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
121943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
121953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1219616ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1219716ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
121983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
121993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
122003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
122013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
122023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
122033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
122043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1220516ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1220616ea139d53d867211d3bb0fa859a83de653f687ecristy%
122073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1220916ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1221016ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
122113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
122123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1221321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1221403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
122163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
122183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
122193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
122213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
122223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
122233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
122243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
122253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
122263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
122273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12228fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1222916ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
122303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
122313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
122323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
122343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
122353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
122363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1223773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
122383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
122393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
122413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
122423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
122433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
122443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
122453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
122463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
122483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1224916ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
122503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
122513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
122533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
122543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
122563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
122573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
122583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
122593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1226016ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1226116ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
122623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
122643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
122653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
122673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
122683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1227021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
122713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
122723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1227303812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1227403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1227503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
122763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
122783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
122803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
122813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
122823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
122853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
122863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
122873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
122883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
122893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
122903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
122913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
122923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12293bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
122943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
122973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
122983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
123003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
123013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12303bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
123043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
123053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12306bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12310d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
123113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
123123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
123133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
123143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
123153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
123183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
123203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12324fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1232516ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
123273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
123283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
123313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1233373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
123343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
123353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
123363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
123403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
123413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
123423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
123433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
123463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
123473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
123483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
123493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
123503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
123513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
123523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
123533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
123563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
123573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
123583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
123603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
123623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
123653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
123683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
123693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
123740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12376e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
123770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
123803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
123833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12385e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
123860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12388e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
123890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
123930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
123970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
123993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
124010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
124050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12408e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
124090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
124113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
124130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
124153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
124163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
124173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
124203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
124213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
124263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
124303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
124313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
124343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
124363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
124373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
124383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
124403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
124453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
124463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
124473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
124483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
124503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
124513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
124523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
124533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
124553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
124573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
124583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
124593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
124603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
124613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
124623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
124633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
124643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
124653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
124683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
124693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
124703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
124713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
124723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
124733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
124743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
124753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
124760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
124783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
124793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
124800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
124823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
124830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
124853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
124860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
124883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
124893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
124903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
124920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
124943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
124950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
124970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
124993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
125003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
125010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
125033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
125043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
125053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
125083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
125090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
125113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1251216ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ImageIsGray(image,exception) == MagickFalse)
125133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
125153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
125163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
125173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
125203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
125213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
125223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
125243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
125253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
125263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
125283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
125290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
125313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
125320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
125360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1253816ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1253916ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
125403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
125410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
125433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
125453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
125463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
125473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
125483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
125493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
125503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
125523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
125533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
125543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
125563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
125583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
125603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
125633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
125643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
125653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
125663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
125673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
125693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
125713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
125723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
125733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
125753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
125763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
125773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
125833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
125843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
125873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
125883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
125893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
125903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
125930261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
12594d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
12595d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1259616ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1259716ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
12598d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
12599d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
12600d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
126043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
126053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
12606cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
12607cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
126083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
126093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
126100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
126123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
126130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
126153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
126160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
126183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
126193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
126203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
126223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
126230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
126253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
126263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
126273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
126283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
126293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
126303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
126313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
126323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
126333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
126343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
126353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
126363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1263703812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
126384e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
126394e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
126403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
126423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
126433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
126443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
126453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
126463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
126473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
126483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
126493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
126500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
126523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
126533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
126540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
126573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
126583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
126590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
126613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
126640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
126683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
126703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
126710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
126750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
126773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
126783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
126793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
126800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
126833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
126883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
126893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
126903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
126963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
126973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
12698bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1269903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
127003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
127013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
127023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
127053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
127063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
127073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
127103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
127113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1271303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
127143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
127153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
127163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
127173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
127180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
127203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
127210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
127240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12728e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
12729e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
127300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
127323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12733e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
127340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
127363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12737e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
127383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
127433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
127453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
127463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
127523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1275303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
127540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
12756e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
12757cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
12758e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
127590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
12761e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
12762cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
12763cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
127640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
127753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
127763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
127773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
127783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1277903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1278035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
127823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
127833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
127863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
127893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
127933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
127943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1279503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1279735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1279835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1280035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1280135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1280335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1280435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1280635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1280735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
128083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
128113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1281316ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
128143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
128163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
128193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1282003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
128210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1282435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1282516ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
128260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1282735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1282816ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
128290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1283735ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1283816ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
128390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1284035ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1284116ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
128420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
128450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
128473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1284816ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1284916ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
128523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
128573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
128603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
128633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
128673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1286803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
128743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
128753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
128763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
128793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
128803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1288103812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
128823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
128833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
128843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
128883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
128893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
128903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
128913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
12892bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
128933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
128963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
128973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
128983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
129003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1290103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
129020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12903bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
129043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1290516ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1290616ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1290716ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1290816ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1290916ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1291016ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
129113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
129120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
129163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
129203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
129243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
129263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
129273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
129283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
129293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
129303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
129313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
129323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
129343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
129363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
129403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
129423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
129433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
129443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
12950bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
129523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
129553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1295603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
129570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12958bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
129603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
129613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
129623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
129633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
129640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
129663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
129673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
129683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
129713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
129743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
129763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
129783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
129793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
129803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
129823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
129843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
129853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
129863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
129893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
129903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
129913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
129923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
129963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1299703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
129983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
129993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
130013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
130043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
130063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
130083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
130093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
130113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
130133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
130163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
130173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
130183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
130193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
130203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
130213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
130243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
130253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1302603812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
130283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
130293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
130303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
130313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
130323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
130333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
130353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
130363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
130373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1303803812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
130393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
130403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
130413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
130423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
130433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
130443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
130453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
130463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
130473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
130483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
130493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
130504e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
130513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
130533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
130563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
130573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
130583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
130603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
130623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
130633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
130653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
130663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1306716ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
130703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
130733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
130743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
130753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
130762f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13077b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
130788d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
130792f2e514554975d510c88df54de98c6cdc1080f1cglennrp
130802f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
130812f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
130822f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13083a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
130842f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
130852f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
130862f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
130872f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
130882f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
130892f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
130902f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
130912f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13092a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
130932f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
130942f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
130952f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
130962f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1309716ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
130983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
130993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
131013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
131023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
131033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
131043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
131073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
131083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
131103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
131113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
131120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
131143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
131150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
131170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
131193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
131203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
131213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
131223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
131233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
131243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1312703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
131293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
131303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
131313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
131333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
131343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
131353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
131360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
131383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
131390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
131413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13142d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1314339992b4dd9b12ef752d55b8e402c069698851f72glennrp
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
131463bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
131473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
131490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
131513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1315339992b4dd9b12ef752d55b8e402c069698851f72glennrp
131543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
131553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
131563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
131573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13158d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
131593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13160