png.c revision c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dc
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"
50aa2c16cb5e695053aa78e40f66bc36fbef4b1ed1cristy#include "MagickCore/channel.h"
5116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/color.h"
5216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/color-private.h"
5316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colormap.h"
5416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colorspace.h"
5516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colorspace-private.h"
5616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/constitute.h"
5716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/enhance.h"
5816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/exception.h"
5916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/exception-private.h"
6016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/geometry.h"
6116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/histogram.h"
6216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/image.h"
6316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/image-private.h"
6416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/layer.h"
6516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/list.h"
6616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/log.h"
6716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/MagickCore.h"
6816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/memory_.h"
6916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/module.h"
7016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/monitor.h"
7116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/monitor-private.h"
7216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/option.h"
7316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/pixel.h"
7416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/pixel-accessor.h"
7516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/profile.h"
7616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/property.h"
7716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/quantum-private.h"
7816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/resource_.h"
7916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/semaphore.h"
8016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/quantum-private.h"
8116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/static.h"
8216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/statistic.h"
8316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/string_.h"
8416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/string-private.h"
8516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/transform.h"
8616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/utility.h"
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
88286a6355c4544b794da2b6df973faad07c69e541glennrp
897ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp/* Suppress libpng pedantic warnings that were added in
907ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * libpng-1.2.41 and libpng-1.4.0.  If you are working on
91faa852bad40107edae19405e76a299057668d795glennrp * migration to libpng-1.5, remove these defines and then
927ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * fix any code that generates warnings.
937ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp */
94991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp/* #define PNG_DEPRECATED   Use of this function is deprecated */
95faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_USE_RESULT   The result of this function must be checked */
96faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_NORETURN     This function does not return */
97faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_ALLOCATED    The result of the function is new memory */
988371ecc013ff231ce380d8717e517312e62e1f01glennrp/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */
995b927348e949d94f3a64b055eccb03459f115c69glennrp
1005b927348e949d94f3a64b055eccb03459f115c69glennrp/* PNG_PTR_NORETURN does not work on some platforms, in libpng-1.5.x */
10175cfe702843fd25dba7cb241c05fa65957c67129cristy#define PNG_PTR_NORETURN
102286a6355c4544b794da2b6df973faad07c69e541glennrp
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1278e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp       (((color).red == (target).red) && \
1288e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp        ((color).green == (target).green) && \
1298e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp        ((color).blue == (target).blue))
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1328e58efdecda887b08ef730d68290a61081ef2566glennrp/* Macros for left-bit-replication to ensure that pixels
13316ea139d53d867211d3bb0fa859a83de653f687ecristy * and PixelInfos all have the same image->depth, and for use
1348e58efdecda887b08ef730d68290a61081ef2566glennrp * in PNG8 quantization.
1358e58efdecda887b08ef730d68290a61081ef2566glennrp */
1368e58efdecda887b08ef730d68290a61081ef2566glennrp
1378e58efdecda887b08ef730d68290a61081ef2566glennrp
1388e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR01: Replicate top bit */
1398e58efdecda887b08ef730d68290a61081ef2566glennrp
14005001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR01PacketRed(pixelpacket) \
1418e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=(ScaleQuantumToChar((pixelpacket).red) < 0x10 ? \
1428e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1438e58efdecda887b08ef730d68290a61081ef2566glennrp
14491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketGreen(pixelpacket) \
1458e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=(ScaleQuantumToChar((pixelpacket).green) < 0x10 ? \
1468e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1478e58efdecda887b08ef730d68290a61081ef2566glennrp
14891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketBlue(pixelpacket) \
1498e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=(ScaleQuantumToChar((pixelpacket).blue) < 0x10 ? \
1508e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1518e58efdecda887b08ef730d68290a61081ef2566glennrp
15216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PacketAlpha(pixelpacket) \
15316ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=(ScaleQuantumToChar((pixelpacket).alpha) < 0x10 ? \
1548e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1558e58efdecda887b08ef730d68290a61081ef2566glennrp
15691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGB(pixelpacket) \
157bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
15805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR01PacketRed((pixelpacket)); \
15991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketGreen((pixelpacket)); \
16091d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketBlue((pixelpacket)); \
161bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1628e58efdecda887b08ef730d68290a61081ef2566glennrp
16391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGBO(pixelpacket) \
164bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
16591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketRGB((pixelpacket)); \
16616ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PacketAlpha((pixelpacket)); \
167bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1688e58efdecda887b08ef730d68290a61081ef2566glennrp
169ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR01PixelRed(pixel) \
17016ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelRed(image,(pixel))) < 0x10 ? \
1718e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1728e58efdecda887b08ef730d68290a61081ef2566glennrp
17354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelGreen(pixel) \
17416ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelGreen(image,(pixel))) < 0x10 ? \
1758e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1768e58efdecda887b08ef730d68290a61081ef2566glennrp
17754cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelBlue(pixel) \
17816ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelBlue(image,(pixel))) < 0x10 ? \
1798e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1808e58efdecda887b08ef730d68290a61081ef2566glennrp
18116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelAlpha(pixel) \
18216ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) < 0x10 ? \
1838e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1848e58efdecda887b08ef730d68290a61081ef2566glennrp
18554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelRGB(pixel) \
186bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
187ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR01PixelRed((pixel)); \
18854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelGreen((pixel)); \
18954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelBlue((pixel)); \
190bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1918e58efdecda887b08ef730d68290a61081ef2566glennrp
19216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelRGBA(pixel) \
193bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
19454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelRGB((pixel)); \
19516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PixelAlpha((pixel)); \
196bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1978e58efdecda887b08ef730d68290a61081ef2566glennrp
1988e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR02: Replicate top 2 bits */
1998e58efdecda887b08ef730d68290a61081ef2566glennrp
20005001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR02PacketRed(pixelpacket) \
2018e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2028e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xc0; \
2038e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2048e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2058e58efdecda887b08ef730d68290a61081ef2566glennrp   }
20691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketGreen(pixelpacket) \
2078e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2088e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xc0; \
2098e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2108e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2118e58efdecda887b08ef730d68290a61081ef2566glennrp   }
21291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketBlue(pixelpacket) \
2138e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2148e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xc0; \
2158e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
2168e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2178e58efdecda887b08ef730d68290a61081ef2566glennrp   }
21816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PacketAlpha(pixelpacket) \
2198e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
22016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xc0; \
22116ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum( \
2228e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2238e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2248e58efdecda887b08ef730d68290a61081ef2566glennrp
22591d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGB(pixelpacket) \
226bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
22705001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR02PacketRed((pixelpacket)); \
22891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketGreen((pixelpacket)); \
22991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue((pixelpacket)); \
230bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2318e58efdecda887b08ef730d68290a61081ef2566glennrp
23291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGBO(pixelpacket) \
233bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
23491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketRGB((pixelpacket)); \
23516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PacketAlpha((pixelpacket)); \
236bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2378e58efdecda887b08ef730d68290a61081ef2566glennrp
238ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR02PixelRed(pixel) \
2398e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
24016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
2418e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
24216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
24316ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
24416ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2458e58efdecda887b08ef730d68290a61081ef2566glennrp   }
24654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelGreen(pixel) \
2478e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
24816ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
2498e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
25016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
25116ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
25216ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2538e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelBlue(pixel) \
2558e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2568e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
25716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xc0; \
25816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
25916ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
26016ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2618e58efdecda887b08ef730d68290a61081ef2566glennrp   }
26216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelAlpha(pixel) \
2638e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2648e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
26516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xc0; \
26616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image, ScaleCharToQuantum( \
26716ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
26816ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel) ); \
2698e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2708e58efdecda887b08ef730d68290a61081ef2566glennrp
27154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelRGB(pixel) \
272bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
273ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR02PixelRed((pixel)); \
27454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelGreen((pixel)); \
27554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelBlue((pixel)); \
276bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2778e58efdecda887b08ef730d68290a61081ef2566glennrp
27816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelRGBA(pixel) \
279bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
28054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelRGB((pixel)); \
28116ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PixelAlpha((pixel)); \
282bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2838e58efdecda887b08ef730d68290a61081ef2566glennrp
2848e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR03: Replicate top 3 bits (only used with opaque pixels during
2858e58efdecda887b08ef730d68290a61081ef2566glennrp   PNG8 quantization) */
2868e58efdecda887b08ef730d68290a61081ef2566glennrp
28705001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR03PacketRed(pixelpacket) \
2888e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2898e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xe0; \
2908e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2918e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
2928e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketGreen(pixelpacket) \
2948e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2958e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xe0; \
2968e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2978e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
2988e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketBlue(pixelpacket) \
3008e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3018e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xe0; \
3028e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
3038e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3048e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3058e58efdecda887b08ef730d68290a61081ef2566glennrp
30691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketRGB(pixelpacket) \
307bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
30805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR03PacketRed((pixelpacket)); \
30991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketGreen((pixelpacket)); \
31091d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketBlue((pixelpacket)); \
311bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3128e58efdecda887b08ef730d68290a61081ef2566glennrp
313ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR03PixelRed(pixel) \
3148e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
31516ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3168e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
31716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
31816ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3198e58efdecda887b08ef730d68290a61081ef2566glennrp   }
32016ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Green(pixel) \
3218e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
32216ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3238e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
32416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
32516ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3268e58efdecda887b08ef730d68290a61081ef2566glennrp   }
32716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Blue(pixel) \
3288e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
32916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelBlue(image,(pixel))) \
3308e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
33116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
33216ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3338e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3348e58efdecda887b08ef730d68290a61081ef2566glennrp
33516ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03RGB(pixel) \
336bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
337ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR03PixelRed((pixel)); \
33816ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Green((pixel)); \
33916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Blue((pixel)); \
340bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3418e58efdecda887b08ef730d68290a61081ef2566glennrp
3428e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR04: Replicate top 4 bits */
3438e58efdecda887b08ef730d68290a61081ef2566glennrp
34405001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR04PacketRed(pixelpacket) \
3458e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3468e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xf0; \
3478e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3488e58efdecda887b08ef730d68290a61081ef2566glennrp   }
34991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketGreen(pixelpacket) \
3508e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3518e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xf0; \
3528e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3538e58efdecda887b08ef730d68290a61081ef2566glennrp   }
35491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketBlue(pixelpacket) \
3558e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3568e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xf0; \
3578e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3588e58efdecda887b08ef730d68290a61081ef2566glennrp   }
35916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PacketAlpha(pixelpacket) \
3608e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
36116ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xf0; \
36216ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3648e58efdecda887b08ef730d68290a61081ef2566glennrp
36591d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGB(pixelpacket) \
366bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
36705001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR04PacketRed((pixelpacket)); \
36891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketGreen((pixelpacket)); \
36991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketBlue((pixelpacket)); \
370bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3718e58efdecda887b08ef730d68290a61081ef2566glennrp
37291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGBO(pixelpacket) \
373bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
37491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB((pixelpacket)); \
37516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PacketAlpha((pixelpacket)); \
376bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3778e58efdecda887b08ef730d68290a61081ef2566glennrp
378ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR04PixelRed(pixel) \
3798e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
38016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3818e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
38216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
38316ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3848e58efdecda887b08ef730d68290a61081ef2566glennrp   }
38554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelGreen(pixel) \
3868e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
38716ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3888e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
38916ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
39016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3918e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39254cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelBlue(pixel) \
3938e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3948e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
39516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xf0; \
39616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
39716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3988e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelAlpha(pixel) \
4008e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4018e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
40216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xf0; \
40316ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
40416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4058e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4068e58efdecda887b08ef730d68290a61081ef2566glennrp
40754cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelRGB(pixel) \
408bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
409ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR04PixelRed((pixel)); \
41054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelGreen((pixel)); \
41154cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelBlue((pixel)); \
412bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4138e58efdecda887b08ef730d68290a61081ef2566glennrp
41416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelRGBA(pixel) \
415bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
41654cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelRGB((pixel)); \
41716ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PixelAlpha((pixel)); \
418bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4198e58efdecda887b08ef730d68290a61081ef2566glennrp
4208e58efdecda887b08ef730d68290a61081ef2566glennrp
4218e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR08: Replicate top 8 bits */
4228e58efdecda887b08ef730d68290a61081ef2566glennrp
42305001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR08PacketRed(pixelpacket) \
4248e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4258e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red); \
4268e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits)); \
4278e58efdecda887b08ef730d68290a61081ef2566glennrp   }
42891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketGreen(pixelpacket) \
4298e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4308e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green); \
4318e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits)); \
4328e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketBlue(pixelpacket) \
4348e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4358e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue); \
4368e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits)); \
4378e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PacketAlpha(pixelpacket) \
4398e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
44016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha); \
44116ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits)); \
4428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4438e58efdecda887b08ef730d68290a61081ef2566glennrp
44491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketRGB(pixelpacket) \
445bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
44605001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR08PacketRed((pixelpacket)); \
44791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketGreen((pixelpacket)); \
44891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketBlue((pixelpacket)); \
449bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4508e58efdecda887b08ef730d68290a61081ef2566glennrp
45191d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketRGBO(pixelpacket) \
452bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
45391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketRGB((pixelpacket)); \
45416ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR08PacketAlpha((pixelpacket)); \
455bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4568e58efdecda887b08ef730d68290a61081ef2566glennrp
457ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR08PixelRed(pixel) \
4588e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4598e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
46016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelRed(image,(pixel))); \
46116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
46216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
46454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelGreen(pixel) \
4658e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4668e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
46716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelGreen(image,(pixel))); \
46816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
46916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4708e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelBlue(pixel) \
4728e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4738e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
47416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))); \
47516ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
47616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4778e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PixelAlpha(pixel) \
4798e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4808e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
48116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))); \
48216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
48316ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4848e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4858e58efdecda887b08ef730d68290a61081ef2566glennrp
48654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelRGB(pixel) \
487bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
488ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR08PixelRed((pixel)); \
48954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelGreen((pixel)); \
49054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelBlue((pixel)); \
491bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4928e58efdecda887b08ef730d68290a61081ef2566glennrp
49316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PixelRGBA(pixel) \
494bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
49554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelRGB((pixel)); \
49616ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR08PixelAlpha((pixel)); \
497bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4988e58efdecda887b08ef730d68290a61081ef2566glennrp
4998e58efdecda887b08ef730d68290a61081ef2566glennrp
5008e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR16: Replicate top 16 bits */
5018e58efdecda887b08ef730d68290a61081ef2566glennrp
50205001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR16PacketRed(pixelpacket) \
5038e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5048e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).red); \
5058e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleShortToQuantum((lbr_bits)); \
5068e58efdecda887b08ef730d68290a61081ef2566glennrp   }
50791d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketGreen(pixelpacket) \
5088e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5098e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).green); \
5108e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleShortToQuantum((lbr_bits)); \
5118e58efdecda887b08ef730d68290a61081ef2566glennrp   }
51291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketBlue(pixelpacket) \
5138e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5148e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).blue); \
5158e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleShortToQuantum((lbr_bits)); \
5168e58efdecda887b08ef730d68290a61081ef2566glennrp   }
51716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PacketAlpha(pixelpacket) \
5188e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
51916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).alpha); \
52016ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleShortToQuantum((lbr_bits)); \
5218e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5228e58efdecda887b08ef730d68290a61081ef2566glennrp
52391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketRGB(pixelpacket) \
524bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
52505001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR16PacketRed((pixelpacket)); \
52691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketGreen((pixelpacket)); \
52791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketBlue((pixelpacket)); \
528bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5298e58efdecda887b08ef730d68290a61081ef2566glennrp
53091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketRGBO(pixelpacket) \
531bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
53291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketRGB((pixelpacket)); \
53316ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR16PacketAlpha((pixelpacket)); \
534bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5358e58efdecda887b08ef730d68290a61081ef2566glennrp
536ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR16PixelRed(pixel) \
5378e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5388e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
53916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelRed(image,(pixel))); \
54016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
54116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
54354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelGreen(pixel) \
5448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5458e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
54616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelGreen(image,(pixel))); \
54716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
54816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5498e58efdecda887b08ef730d68290a61081ef2566glennrp   }
55054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelBlue(pixel) \
5518e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5528e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
55316ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelBlue(image,(pixel))); \
55416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
55516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5568e58efdecda887b08ef730d68290a61081ef2566glennrp   }
55716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PixelAlpha(pixel) \
5588e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5598e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
56016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelAlpha(image,(pixel))); \
56116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
56216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5648e58efdecda887b08ef730d68290a61081ef2566glennrp
56554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelRGB(pixel) \
566bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
567ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR16PixelRed((pixel)); \
56854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelGreen((pixel)); \
56954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelBlue((pixel)); \
570bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5718e58efdecda887b08ef730d68290a61081ef2566glennrp
57216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PixelRGBA(pixel) \
573bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
57454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelRGB((pixel)); \
57516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR16PixelAlpha((pixel)); \
576bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5778e58efdecda887b08ef730d68290a61081ef2566glennrp
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
587edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
589cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  *ping_semaphore = (SemaphoreInfo *) NULL;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
626bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
64185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
64285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
64385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
64485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
64585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
64685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
64785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
64885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
64985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
65085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
65185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
65285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
65385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
65485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
65585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
65685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
65785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
65885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
65985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
66085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
66185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
66285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
66385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
66485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
66585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
66685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
66785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
66885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
66985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
67085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
67185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
67285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
67385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
67685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
67785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
67885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
67985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
68085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
68185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
68685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
68785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
68885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
68985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
69085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
69185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
69285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
69385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
794bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84035ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
850b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
851b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
852b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
8701868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_level,
8711868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_strategy,
8721868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_filter,
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
878bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90716ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
91126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
91226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
91326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
914a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
91526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
91626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
91726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
91826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
91926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
92026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
92126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
92226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
923a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
92426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
92526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
9268d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_exclude_zTXt,
9278d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap;
92826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
93616ea139d53d867211d3bb0fa859a83de653f687ecristy  WritePNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9370c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
93916ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteMNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
94316ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteJNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
9470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
948fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
9500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
95116ea139d53d867211d3bb0fa859a83de653f687ecristyLosslessReduceDepthOK(Image *image,ExceptionInfo *exception)
9520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
9539d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp    /* Reduce bit depth if it can be reduced losslessly from 16+ to 8.
95467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
95567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * This is true if the high byte and the next highest byte of
95667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * each sample of the image, the colormap, and the background color
9573faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are equal to each other.  We check this by seeing if the samples
9583faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are unchanged when we scale them down to 8 and back up to Quantum.
95967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
96067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * We don't use the method GetImageDepth() because it doesn't check
9613faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * background and doesn't handle PseudoClass specially.
9629d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp     */
96305a549971fd661147ade177e2bc10f6cfcfc32b4glennrp
9643faa9a3fb01696daaf976d595f492cb530bffb21glennrp#define QuantumToCharToQuantumEqQuantum(quantum) \
9653faa9a3fb01696daaf976d595f492cb530bffb21glennrp  ((ScaleCharToQuantum((unsigned char) ScaleQuantumToChar(quantum))) == quantum)
9663faa9a3fb01696daaf976d595f492cb530bffb21glennrp
96767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    MagickBooleanType
96867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      ok_to_reduce=MagickFalse;
96967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
97003e11f6e8d7f01a32b53d7e8e6a3bfd5ef1c5c9dglennrp    if (image->depth >= 16)
9710c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
9720c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
97316ea139d53d867211d3bb0fa859a83de653f687ecristy        const Quantum
9740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
9750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9760c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
9773faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.red) &&
9783faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.green) &&
9793faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.blue) ?
9803faa9a3fb01696daaf976d595f492cb530bffb21glennrp           MagickTrue : MagickFalse;
9810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
9830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
9840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
9850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
9870c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
9883faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=(
9893faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9903faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].red) &&
9913faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9923faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].green) &&
9933faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9943faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].blue)) ?
9953faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
9963faa9a3fb01696daaf976d595f492cb530bffb21glennrp
9970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
9983faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   break;
9990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
10000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
10010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
10030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
10040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
10050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
10060c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
10070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10080c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
10090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
10100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
10120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
101316ea139d53d867211d3bb0fa859a83de653f687ecristy              p=GetVirtualPixels(image,0,y,image->columns,1,exception);
10140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
101516ea139d53d867211d3bb0fa859a83de653f687ecristy              if (p == (const Quantum *) NULL)
10160c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
10170c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
10180c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
10200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
10220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
10233faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=
102416ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelRed(image,p)) &&
102516ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelGreen(image,p)) &&
102616ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelBlue(image,p)) ?
10273faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
10280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
10300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
103216ea139d53d867211d3bb0fa859a83de653f687ecristy                p+=GetPixelChannels(image);
10330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
10348640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
10350c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
10360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
10370c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
10380c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
10400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
10410c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1042fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    OK to reduce PNG bit depth to 8 without loss of info");
10430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
1044a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
1045a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
1046a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1047fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    Not OK to reduce PNG bit depth to 8 without loss of info");
1048a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
10490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
10500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
10520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
10530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
10540c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10551a56e9c9268976936eeab9fe97eb664b847e444cglennrpstatic const char* PngColorTypeToString(const unsigned int color_type)
10561a56e9c9268976936eeab9fe97eb664b847e444cglennrp{
10571a56e9c9268976936eeab9fe97eb664b847e444cglennrp  const char
10581a56e9c9268976936eeab9fe97eb664b847e444cglennrp    *result = "Unknown";
10591a56e9c9268976936eeab9fe97eb664b847e444cglennrp
10601a56e9c9268976936eeab9fe97eb664b847e444cglennrp  switch (color_type)
10611a56e9c9268976936eeab9fe97eb664b847e444cglennrp    {
10621a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY:
10631a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray";
10641a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10651a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY_ALPHA:
10661a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray+Alpha";
10671a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10681a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_PALETTE:
10691a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Palette";
10701a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10711a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB:
10721a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB";
10731a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10741a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB_ALPHA:
10751a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB+Alpha";
10761a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10771a56e9c9268976936eeab9fe97eb664b847e444cglennrp    }
10781a56e9c9268976936eeab9fe97eb664b847e444cglennrp
10791a56e9c9268976936eeab9fe97eb664b847e444cglennrp  return result;
10801a56e9c9268976936eeab9fe97eb664b847e444cglennrp}
10811a56e9c9268976936eeab9fe97eb664b847e444cglennrp
1082e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
1083cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
10840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1085e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
1086e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1087e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
1088e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
10890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1090e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
1091e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
10920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1093e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
1094e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
10950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1096e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
1097e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
10980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1099e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1100e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
1101e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
1102e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1103e610a071534e448c46460a5aa39ede33bf56b329glennrp
1104e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
1105cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_from_PNG_RenderingIntent(const int ping_intent)
11060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1107cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  switch (ping_intent)
1108e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1109e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
1110e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
11110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1112e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
1113e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
11140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1115e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
1116e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
11170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1118e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
1119e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
11200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1121e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1122e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
1123e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
1124e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1125e610a071534e448c46460a5aa39ede33bf56b329glennrp
11269d8c12213abd15fee2d84da62d3e5145d9db06cdcristystatic const char *
112798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrpMagick_RenderingIntentString_from_PNG_RenderingIntent(const int ping_intent)
112898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp{
112998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  switch (ping_intent)
113098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
113198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 0:
113298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Perceptual Intent";
113398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
113498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 1:
113598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Relative Intent";
113698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
113798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 2:
113898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Saturation Intent";
113998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
114098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 3:
114198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Absolute Intent";
114298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
114398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    default:
114498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Undefined Intent";
114598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
114698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp}
114798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
1148bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
11520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
1156d9ecd04e9c567113b4b605cf76681cbb37c093cdcristystatic const char *
11575dff435eceea4f80207a906b11e65aed48fe3f27glennrpMagick_ColorType_from_PNG_ColorType(const int ping_colortype)
11585dff435eceea4f80207a906b11e65aed48fe3f27glennrp{
11595dff435eceea4f80207a906b11e65aed48fe3f27glennrp  switch (ping_colortype)
11605dff435eceea4f80207a906b11e65aed48fe3f27glennrp  {
11615dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 0:
11625dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Grayscale";
11635dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11645dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 2:
11655dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Truecolor";
11665dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11675dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 3:
11685dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Indexed";
11695dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11705dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 4:
11715dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "GrayAlpha";
11725dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11735dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 6:
11745dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "RGBA";
11755dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11765dff435eceea4f80207a906b11e65aed48fe3f27glennrp    default:
11775dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "UndefinedColorType";
11785dff435eceea4f80207a906b11e65aed48fe3f27glennrp    }
11795dff435eceea4f80207a906b11e65aed48fe3f27glennrp}
11805dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11815dff435eceea4f80207a906b11e65aed48fe3f27glennrp
1182bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
11860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1189d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1307d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1308bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1330a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1338a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135103812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
135203812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1356e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
1357e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1359d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1365d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
1447f54e295d6fa414fa04aa4f43767c20eda8ae555eglennrp%    the original PNG from files that have been converted to Xcode-PNG,
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14783b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy          (void) FormatLocaleString(msg,MaxTextExtent,
1479e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1480e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1508bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
15240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
15270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
15850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
16180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
16330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
16380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1653bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
165721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
165821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
166021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1662bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
16670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
16710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
16850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
16880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
16910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
16940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1706bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1709bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1727bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17298182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
17308182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
17310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17418182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
174616ea139d53d867211d3bb0fa859a83de653f687ecristytypedef struct _PNGErrorInfo
174716ea139d53d867211d3bb0fa859a83de653f687ecristy{
174816ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
174916ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
175016ea139d53d867211d3bb0fa859a83de653f687ecristy
175116ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
175216ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
175316ea139d53d867211d3bb0fa859a83de653f687ecristy} PNGErrorInfo;
175416ea139d53d867211d3bb0fa859a83de653f687ecristy
1755cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
175716ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
175816ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
175916ea139d53d867211d3bb0fa859a83de653f687ecristy
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
176316ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
176416ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
17650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
176616ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
176716ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
176816ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
1769c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy
177016ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
177116ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
177216ea139d53d867211d3bb0fa859a83de653f687ecristy
177316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,message,
177416ea139d53d867211d3bb0fa859a83de653f687ecristy    "`%s'",image->filename);
17750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1776e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
17778371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
17788371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
17798371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1781faa852bad40107edae19405e76a299057668d795glennrp#else
1782faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1783faa852bad40107edae19405e76a299057668d795glennrp#endif
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1786cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
178816ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
178916ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
179016ea139d53d867211d3bb0fa859a83de653f687ecristy
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
179416ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
179516ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
179616ea139d53d867211d3bb0fa859a83de653f687ecristy
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
17990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
180016ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
180116ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
180216ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
180316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
180416ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
18050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
180616ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1811a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
1812a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_alloc_size_t size)
1813a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
1814a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_size_t size)
1815a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1817df0d90e1d3bbfa3956818ac7bf43aa0d008020dccristy  (void) png_ptr;
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1824cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
18263bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) png_ptr;
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1837edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrpMagick_png_read_raw_profile(png_struct *ping,Image *image,
1838edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   const ImageInfo *image_info, png_textp text,int ii,ExceptionInfo *exception)
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1840bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1873f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
18740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
187597f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
187697f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
187797f90e23c85b9c58387880125c29d8c99126f83aglennrp
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1884edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping,"invalid profile length");
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18888723e4bcd840478cecfd29891e792edb499cd0e9cristy  profile=BlobToStringInfo((const void *) NULL,length);
18890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1892edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping, "unable to copy profile");
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
18990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1900bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1906edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp          png_warning(ping, "ran out of profile data");
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
19150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
192216ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProfile(image,&text[ii].key[17],profile,exception);
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
19240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
19270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1961bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
19630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1964bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2012cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tIME chunk into the date:modify property */
2013cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tEXt/Creation Time chunk into the date:create property */
2014cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
201998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    intent, /* "PNG Rendering intent", which is ICC intent + 1 */
2020cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
20224eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
2024913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp    number_colors,
2025faa852bad40107edae19405e76a299057668d795glennrp    pass,
2026faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
2027faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
2028fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp    ping_file_depth,
2029faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
2030faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
2031faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
20324eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
20334eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
20344eb3931feb349dd87142c78503b779228f3e1a0fglennrp
20354eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
20364eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
20394383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
204098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_cHRM,
204198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_gAMA,
204298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_iCCP,
204398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_sRGB,
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
204616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
204716ea139d53d867211d3bb0fa859a83de653f687ecristy    transparent_color;
204816ea139d53d867211d3bb0fa859a83de653f687ecristy
204916ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
205016ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
205116ea139d53d867211d3bb0fa859a83de653f687ecristy
2052faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
2053faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
2054faa852bad40107edae19405e76a299057668d795glennrp
2055faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
2056faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
2057faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
2058faa852bad40107edae19405e76a299057668d795glennrp
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2069faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
2070faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
2071faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
20724eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
20734eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
2074faa852bad40107edae19405e76a299057668d795glennrp
207516ea139d53d867211d3bb0fa859a83de653f687ecristy  QuantumInfo
207616ea139d53d867211d3bb0fa859a83de653f687ecristy    *quantum_info;
207716ea139d53d867211d3bb0fa859a83de653f687ecristy
2078bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2079756ae430d36380dfab8ca703538f5922f3796351cristy    ping_rowbytes,
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2085bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
208916ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
209339992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2096eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
2097eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
2098eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
209975fc68f33e6e766a22e8ed653c3ed50b0d142827cristy  unsigned char
210075fc68f33e6e766a22e8ed653c3ed50b0d142827cristy    *volatile ping_pixels;
210155b78b53f1e013e0af19565ac04aaa7660d53795cristy
2102629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
2111629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_APNG_SUPPORTED /* libpng was built with APNG patch; */
2112629960f505ebba710ec9b6953a539a21dab176f2glennrp                          /* ignore the APNG chunks */
2113629960f505ebba710ec9b6953a539a21dab176f2glennrp     97,  99,  84,  76, (png_byte) '\0',   /* acTL */
2114629960f505ebba710ec9b6953a539a21dab176f2glennrp    102,  99,  84,  76, (png_byte) '\0',   /* fcTL */
2115629960f505ebba710ec9b6953a539a21dab176f2glennrp    102, 100,  65,  84, (png_byte) '\0',   /* fdAT */
2116629960f505ebba710ec9b6953a539a21dab176f2glennrp#endif
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
2121fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
212325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
212961b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
213061b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
213161b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
213261b4c957269727a0a2526edc2331881da8346100glennrp    {
213361b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
213461b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
213561b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
213661b4c957269727a0a2526edc2331881da8346100glennrp    }
213761b4c957269727a0a2526edc2331881da8346100glennrp#  endif
213861b4c957269727a0a2526edc2331881da8346100glennrp#endif
213961b4c957269727a0a2526edc2331881da8346100glennrp
214016ea139d53d867211d3bb0fa859a83de653f687ecristy
214116ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info = (QuantumInfo *) NULL;
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2144a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
214598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
2146a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
21478a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      "  image->alpha_trait=%d",(int) image->alpha_trait);
2148a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
214998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
215098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      "  image->rendering_intent=%d",(int) image->rendering_intent);
2151e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
2152e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2153e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp      "  image->colorspace=%d",(int) image->colorspace);
215498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  }
215598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  intent=Magick_RenderingIntent_to_PNG_RenderingIntent(image->rendering_intent);
215698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
21570e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
21580e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
21590e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
21600e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
216116ea139d53d867211d3bb0fa859a83de653f687ecristy  transparent_color.alpha=65537;
21620e319739731741c52a6303723e0c8678a0df5579glennrp
2163913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp  number_colors=0;
2164cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
21654eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
2166cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
2167cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
216898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_cHRM = MagickFalse;
216998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_gAMA = MagickFalse;
217098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_iCCP = MagickFalse;
217198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_sRGB = MagickFalse;
217298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
217716ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
217816ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
217916ea139d53d867211d3bb0fa859a83de653f687ecristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
2180cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
2181cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
218316ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,&error_info,
2184cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
21900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
21980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2205cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
22060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2207faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2213edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2214edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
2215cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2217edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2218edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (ping_pixels != (unsigned char *) NULL)
2219edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
2220edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
22240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
22267b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
222716ea139d53d867211d3bb0fa859a83de653f687ecristy          InheritException(exception,exception);
22287b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
22297b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
22300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2233edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2234edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
2235edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
2236edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
2237edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
2238edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2239edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
2240edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
2241edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
2242edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2246faa852bad40107edae19405e76a299057668d795glennrp
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
22490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22829bf97b6c2143eb20c330346b01e82102cc082725glennrp#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
22839bf97b6c2143eb20c330346b01e82102cc082725glennrp    /* Disable new libpng-1.5.10 feature */
22849bf97b6c2143eb20c330346b01e82102cc082725glennrp    png_set_check_for_invalid_index (ping, 0);
22859bf97b6c2143eb20c330346b01e82102cc082725glennrp#endif
22869bf97b6c2143eb20c330346b01e82102cc082725glennrp
2287991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2288991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2289991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2303991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2307faa852bad40107edae19405e76a299057668d795glennrp
2308faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2309faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2310faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2311faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2312faa852bad40107edae19405e76a299057668d795glennrp
2313fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp  ping_file_depth = ping_bit_depth;
2314fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp
2315faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2316faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2317faa852bad40107edae19405e76a299057668d795glennrp
2318faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2319faa852bad40107edae19405e76a299057668d795glennrp
2320faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2322fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       png_set_packing(ping);
2323fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       ping_bit_depth = 8;
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2325faa852bad40107edae19405e76a299057668d795glennrp
2326faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2328faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
232998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2330176b29a003f11fd934137871d574995319408665cristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2331176b29a003f11fd934137871d574995319408665cristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2332176b29a003f11fd934137871d574995319408665cristy    {
2333176b29a003f11fd934137871d574995319408665cristy      image->rendering_intent=UndefinedIntent;
233498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      intent=Magick_RenderingIntent_to_PNG_RenderingIntent(UndefinedIntent);
2335176b29a003f11fd934137871d574995319408665cristy      image->gamma=1.000;
2336176b29a003f11fd934137871d574995319408665cristy      (void) ResetMagickMemory(&image->chromaticity,0,
2337176b29a003f11fd934137871d574995319408665cristy        sizeof(image->chromaticity));
2338176b29a003f11fd934137871d574995319408665cristy    }
233998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2343e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
2344e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
23450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
2348faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
23490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
2352faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
23530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
2356faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
235998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
236098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
236198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_gAMA=MagickTrue;
236298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
236398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
236498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG gAMA chunk.");
236598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
236698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
236798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
236898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
236998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_cHRM=MagickTrue;
237098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
237198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
237298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG cHRM chunk.");
237398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
237498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
237598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
237698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
237798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_iCCP=MagickTrue;
237898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
237998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
238098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG iCCP chunk.");
238198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
238298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
238398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
238498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
238598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_sRGB=MagickTrue;
238698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
238798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
238898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG sRGB chunk.");
238998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
239098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2391faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2392faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2397e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2398e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2399e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2400e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2401e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2402e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2403e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2404e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
24130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
2422e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          profile=BlobToStringInfo(info,profile_length);
2423e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          if (profile == (StringInfo *) NULL)
2424edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2425edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              png_warning(ping, "ICC profile is NULL");
2426edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              profile=DestroyStringInfo(profile);
2427edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2428edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp          else
2429edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2430edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              (void) SetImageProfile(image,"icc",profile,exception);
2431edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              profile=DestroyStringInfo(profile);
2432edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
24392ea7a8e883de7623d345f32f90ee99248a4a867ecristy      {
24402ea7a8e883de7623d345f32f90ee99248a4a867ecristy        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
24412ea7a8e883de7623d345f32f90ee99248a4a867ecristy          (mng_info->global_srgb_intent);
24422ea7a8e883de7623d345f32f90ee99248a4a867ecristy      }
24430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2446cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
2447cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
24480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2451e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2456faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2457faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2458faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
24590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
246898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2469faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2470faa852bad40107edae19405e76a299057668d795glennrp    {
2471faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2472faa852bad40107edae19405e76a299057668d795glennrp        {
2473faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2474faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2475faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2476faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2477faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2478faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2479faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2480faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2481faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2482faa852bad40107edae19405e76a299057668d795glennrp        }
2483faa852bad40107edae19405e76a299057668d795glennrp    }
24840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2485faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
24960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2499e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
25003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2501e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
2502cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
2503cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
2504da7803d6b1161960bc1e7db4d9718284c116fab8cristy      png_set_gAMA(ping,ping_info,1.000f/2.200f);
2505faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
2506faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
2507faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2510faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2512905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2513905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
25140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2518e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2519e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2523faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2524faa852bad40107edae19405e76a299057668d795glennrp    {
2525faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2526faa852bad40107edae19405e76a299057668d795glennrp        {
2527faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2528faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2529faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2530faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2531faa852bad40107edae19405e76a299057668d795glennrp        }
2532faa852bad40107edae19405e76a299057668d795glennrp    }
2533faa852bad40107edae19405e76a299057668d795glennrp
2534faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
25400881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
254116ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.x=(double) x_resolution;
254216ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.y=(double) y_resolution;
25430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
254716ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.x=(double) x_resolution/100.0;
254816ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.y=(double) y_resolution/100.0;
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
25500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2553e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2554e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2557823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2558faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
25640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2566faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
25720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2573faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2574edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              {
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
2577edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                    png_warning(ping,
2578edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                      "global tRNS has more entries than global PLTE");
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2580edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                else
2581edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  {
2582edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                     png_set_tRNS(ping,ping_info,mng_info->global_trns,
2583edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                       (int) mng_info->global_trns_length,NULL);
2584edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  }
2585edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               }
2586bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2591faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2600faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2601faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
26020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
26050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
26080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
26110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2612c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2613c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2614c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2620edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"No global PLTE in file");
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2624bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2625faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2626faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
26280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2629faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2631bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2632bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2633bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
26400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2641bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      /* Scale background components to 16-bit, then scale
2642bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2643bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
2644bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2645bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2646bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    raw ping_background=(%d,%d,%d).",ping_background->red,
2647bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            ping_background->green,ping_background->blue);
26482cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2649bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
26500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2651fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth == 1)
2652bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
26530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2654fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 2)
2655bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
26560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2657fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 4)
2658bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
26590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2660fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth <= 8)
2661bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
26622cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2663bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2664bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2665bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
26662cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2667bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2668bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
26692cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26702cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
26710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26722cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26732cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
26742cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
2675bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
26762cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2677bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2678faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
26790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2680bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2681faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
26820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2683bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2684bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
26850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
268616ea139d53d867211d3bb0fa859a83de653f687ecristy        image->background_color.alpha=OpaqueAlpha;
26872cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2688bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2689bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2690bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2691bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2692bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2693bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2695bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2696a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2697faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2700a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
270535ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
270635ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
270735ef824baa82511126ff0072ae30eee0da9c05a3cristy
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2712fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      max_sample = (int) ((one << ping_file_depth) - 1);
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2714faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2715faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2716faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2717faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2718faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2719faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2725faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
27268a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          image->alpha_trait=UndefinedPixelTrait;
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2730a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2731a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2732a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2733fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale_to_short = 65535L/((1UL << ping_file_depth)-1);
2734a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2735a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2736a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2737a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2738a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
273916ea139d53d867211d3bb0fa859a83de653f687ecristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
274005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2741faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27430f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
27440f111984738842d27d04aed2a3f823d82a943506glennrp              {
27450f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27460f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
27470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27480f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
274916ea139d53d867211d3bb0fa859a83de653f687ecristy                  "    scaled graylevel is %.20g.",transparent_color.alpha);
27500f111984738842d27d04aed2a3f823d82a943506glennrp              }
275116ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.red=transparent_color.alpha;
275216ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.green=transparent_color.alpha;
275316ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.blue=transparent_color.alpha;
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2760faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2765faa852bad40107edae19405e76a299057668d795glennrp
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2767faa852bad40107edae19405e76a299057668d795glennrp
2768faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2769faa852bad40107edae19405e76a299057668d795glennrp
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2779faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2780faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2791faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2792faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2793a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
279416ea139d53d867211d3bb0fa859a83de653f687ecristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
279516ea139d53d867211d3bb0fa859a83de653f687ecristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
27968d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    {
2797e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp      if ((!png_get_valid(ping,ping_info,PNG_INFO_gAMA) ||
2798e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp          image->gamma == 1.0) &&
27998d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          !png_get_valid(ping,ping_info,PNG_INFO_cHRM) &&
28008d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          !png_get_valid(ping,ping_info,PNG_INFO_sRGB))
28018d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        {
28028d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          /* Set image->gamma to 1.0, image->rendering_intent to Undefined,
2803e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp           * image->colorspace to GRAY, and reset image->chromaticity.
28048d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp           */
28058d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          SetImageColorspace(image,GRAYColorspace,exception);
28068d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        }
28078d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    }
2808e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
2809e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp  (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2810e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp      "  image->colorspace=%d",(int) image->colorspace);
2811a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
2812faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
281332340ffa74550819f755f966e397ed58bbccd8e5glennrp      ((int) ping_bit_depth < 16 &&
281432340ffa74550819f755f966e397ed58bbccd8e5glennrp      (int) ping_color_type == PNG_COLOR_TYPE_GRAY))
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2816befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2817befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2818befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2820befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2821fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      image->colors=one << ping_file_depth;
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
282467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
282567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
282667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
282767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2829faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
28333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2835bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
28360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
28403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
284816ea139d53d867211d3bb0fa859a83de653f687ecristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
2849edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
28500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2851faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
28570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28586af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
28593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
28646af6cf1a950b111ad0ac706269a703086693ba71glennrp
286567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
28666af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
28676af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
28686af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
28696af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
28706af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2875bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2878fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale=(QuantumRange/((1UL << ping_file_depth)-1));
28790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
28820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
28853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
28863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
28883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2891147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2892cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
2893cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
2894147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
2895147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
2896147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2897fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     /* encode ping_width, ping_height, ping_file_depth, ping_color_type,
2898147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
2899147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
29003b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,
29017cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
290216ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.width,height    ",msg,exception);
2903147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2904fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_file_depth);
290516ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.bit_depth       ",msg,exception);
2906147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
29075dff435eceea4f80207a906b11e65aed48fe3f27glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d (%s)",
29085dff435eceea4f80207a906b11e65aed48fe3f27glennrp         (int) ping_color_type,
29095dff435eceea4f80207a906b11e65aed48fe3f27glennrp         Magick_ColorType_from_PNG_ColorType((int)ping_color_type));
291016ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.color_type      ",msg,exception);
2911147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2912913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (ping_interlace_method == 0)
2913913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
2914913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Not interlaced)",
2915913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
2916913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
2917913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else if (ping_interlace_method == 1)
2918913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
2919913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Adam7 method)",
2920913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
2921913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
2922913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else
2923913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
2924913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Unknown method)",
2925913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
2926913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
2927913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
2928913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp
2929913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (number_colors != 0)
2930913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
2931913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d",
2932913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) number_colors);
2933913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) SetImageProperty(image,"png:PLTE.number_colors   ",msg,
2934913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            exception);
2935913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
2936cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
2937147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
29430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29440ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2945347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2946347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29481b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
29491b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
29501b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
29511b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2954e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2957edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2958edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
2959cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2961edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
29650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
29720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
2974cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2975cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
29760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2978cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
2979cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
29800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2981cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
2982edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation failed");
29830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
299016ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info=AcquireQuantumInfo(image_info,image);
299116ea139d53d867211d3bb0fa859a83de653f687ecristy
299216ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
2993edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping,"Failed to allocate quantum_info");
29940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2995c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2996c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2997c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2998c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2999c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3000c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
3001c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3004c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
3005c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3006c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
3007c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
3008c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
30098a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
3010c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
3011c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3012b0a657e13c4aefba39c51292005427b47277869dcristy            BlendPixelTrait : UndefinedPixelTrait;
30130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3014c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
3015c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
3016c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
3017c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
30180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3019c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
3020c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
30210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3022cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
3023c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3024c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          if (pass < num_passes-1)
3025c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp            continue;
3026c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3027862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
302916ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
3030c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
30310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
303216ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
303316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
303416ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
30350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
303616ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
303716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
303816ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
30390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
304016ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
304116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
304216ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
30430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
304416ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
304516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
304616ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
30470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
304816ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
304916ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
305016ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
30513faa9a3fb01696daaf976d595f492cb530bffb21glennrp
3052c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
3053c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3054c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
3055a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
3056a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3057a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
3058a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3059c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3060c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
30615aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
30625aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
306316ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
3064c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
3065a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3066a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3067a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
3068a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3069c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
3070c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
3071c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
30724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
30734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
307416ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
307516ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
307616ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
307716ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
307816ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
307916ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
30804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
3081a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3082a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3083a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
30844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
30854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
30864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
308716ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
3088c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
3089c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
30900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3091c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
3092c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3093c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
3094c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
30950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3096c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
3097c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
3098c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
3099c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
3100c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
3101c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
31020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3103c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
31047a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3105c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
31067a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
31077a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
31087a287bfadeadea12e47c2376ca78a5d101687142cristy          }
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3113c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3125c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3126c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3127c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
312816ea139d53d867211d3bb0fa859a83de653f687ecristy
31298a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
3130b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
31310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
3133b0a657e13c4aefba39c51292005427b47277869dcristy        (image->alpha_trait  == BlendPixelTrait?  2 : 1)*
3134b0a657e13c4aefba39c51292005427b47277869dcristy        sizeof(*quantum_scanline));
31350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
3137edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
31380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3139bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3142faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3143c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3146c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3147cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
3148c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3149c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp        if (pass < num_passes-1)
3150c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          continue;
3151c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
31530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
315416ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
31560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3157cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3159c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3160faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3164faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3165bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3167a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
316816ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) *p++),q);
316916ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetPixelAlpha(image,q) != OpaqueAlpha)
31700b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
317116ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
31730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3175bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3176a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
31770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
318047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3183bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3184a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
3185c17d96f447438bb27d874f1440ed05f6493fde1fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
318658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              size_t
318758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
318858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
318958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3190c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
319158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
319258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3193c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
319458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
319558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3196c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
319758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
31980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3199faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3201c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3202c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3203c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3204c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3205c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3206c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
320716ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,ScaleShortToQuantum(quantum),q);
320816ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
320958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
321016ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
321158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
321258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
321358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
321458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
321558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
321647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
321758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
321858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
321916ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
322016ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
32210b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
322258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
322316ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3226a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
322747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
323047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32343faa9a3fb01696daaf976d595f492cb530bffb21glennrp
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
32390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
324016ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
324116ea139d53d867211d3bb0fa859a83de653f687ecristy
324216ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
324316ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3244bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
324516ea139d53d867211d3bb0fa859a83de653f687ecristy        {
324616ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
324716ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
324816ea139d53d867211d3bb0fa859a83de653f687ecristy        }
32490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
32520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32537a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
32547a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3255cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
32569fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
325747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32587a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
32597a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
32607a287bfadeadea12e47c2376ca78a5d101687142cristy          }
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3262c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32637a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
326647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3270c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3273c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3274b0a657e13c4aefba39c51292005427b47277869dcristy    image->alpha_trait=found_transparent_pixel ? BlendPixelTrait :
3275b0a657e13c4aefba39c51292005427b47277869dcristy      UndefinedPixelTrait;
3276c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3277c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3278c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3279c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3280c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3281c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3282c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
32835aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
32845aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32855aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3286bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
32875aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
32885aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3289c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3290c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3291c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
329216ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
329316ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
329416ea139d53d867211d3bb0fa859a83de653f687ecristy
32955c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
32965c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3297b0a657e13c4aefba39c51292005427b47277869dcristy      PixelTrait
3298b0a657e13c4aefba39c51292005427b47277869dcristy        alpha_trait;
32995c6f789db7a30bad01ace12b09ad9cd471339e94cristy
3300b0a657e13c4aefba39c51292005427b47277869dcristy      alpha_trait=image->alpha_trait;
33018a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
330216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3303b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait=alpha_trait;
33045c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
330547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33064eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3309bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3312cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
331416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
3315edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
3316cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
332347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3324faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
33338a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=BlendPixelTrait;
3334c11cf6a442f3046940608a5743a68cc891deb13eglennrp
33353c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3336c11cf6a442f3046940608a5743a68cc891deb13eglennrp
33370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
33380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
33390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3340c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
33410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
33420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
33438a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                 image->colormap[x].alpha_trait=BlendPixelTrait;
334416ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
334516ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
33460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3347c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
334847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
33500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
33510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
33520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
33530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
335416ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
33550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
33568a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->colormap[x].alpha_trait=BlendPixelTrait;
335716ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
33580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
33590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
33600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
336116ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
33620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
336347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3364a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3365a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3366a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
33670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
33680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
33690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
33700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
33710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
33720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3373c11cf6a442f3046940608a5743a68cc891deb13eglennrp
337416ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
33750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3376c11cf6a442f3046940608a5743a68cc891deb13eglennrp
33770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3378a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3379a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3380a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
33810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
33820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
338316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
338416ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
338516ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
338616ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
338716ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
338816ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
33894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
339016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
33914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
33920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
339367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
33940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
33954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
339616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
33974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3398a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
33990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
340016ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
34010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
34020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
34040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3405c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
34060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3407a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3408c11cf6a442f3046940608a5743a68cc891deb13eglennrp
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
34113c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3412eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
34134eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
34144eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3415a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3416a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
34174eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3418a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3419a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34214eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
34224eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
34234eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
34244eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
34250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34264eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
34274eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34284eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
34290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34304eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
34314eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
3432edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            (void) Magick_png_read_raw_profile(ping,image,image_info,text,
3433edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               (int) i,exception);
34344eb3931feb349dd87142c78503b779228f3e1a0fglennrp            num_raw_profiles++;
34354eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
34364eb3931feb349dd87142c78503b779228f3e1a0fglennrp
34374eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
34384eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
34394eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
34404eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
34414eb3931feb349dd87142c78503b779228f3e1a0fglennrp
34424eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
34434eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
34444eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
34454eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
34464eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
3447edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"Memory allocation failed");
34484eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
34494eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
34504eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
34514eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
34524eb3931feb349dd87142c78503b779228f3e1a0fglennrp
34534eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
34544eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
34554eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
34564eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
34574eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
34584eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
345916ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34614eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
34634eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34644eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      length: %lu",(unsigned long) length);
34654eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34664eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      Keyword: %s",text[i].key);
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
34680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34694eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
347097f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
34714eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
34724eb3931feb349dd87142c78503b779228f3e1a0fglennrp      num_text_total += num_text;
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
34743c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
348773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
34880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
349547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
3500edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp             png_error(ping,"Memory allocation failed");
35010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
3503edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping,"Cannot overwrite frozen MNG object buffer");
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
35050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
35120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
351416ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
35150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
35180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
3520edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping, "Cloning image for object buffer failed");
35210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3522faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
35240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3525faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3526faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3527faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3528faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3529faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3530faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3531faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3532faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
35330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3534faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
35443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
355047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
35560a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
35578a46d827a124555f0c48fb2368ec1bba8e079ab6cristy   /* Set image->alpha_trait to MagickTrue if the input colortype supports
35580a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
35590a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
35600a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
35618a46d827a124555f0c48fb2368ec1bba8e079ab6cristy    image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
35620a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
35630a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3564b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
35650a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3566cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3567cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3568cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3569cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3570cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35714eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3572cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3573cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
35743b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3575613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
357616ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text                 ",msg,
357716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3578cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3579cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3580cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3581cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
35823b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3583cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
358416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
358516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3586cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3587cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
358898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_cHRM != MagickFalse)
35895961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
35903b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
35915961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
359216ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:cHRM                 ",msg,
359316ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
35945961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3595cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3596cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
35975961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
35983b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
35995961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
360016ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:bKGD                 ",msg,
360116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36025961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
36035961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
36043b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%s",
36055961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3606cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
360798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#if defined(PNG_iCCP_SUPPORTED)
360898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_iCCP != MagickFalse)
360916ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageProperty(image,"png:iCCP                 ",msg,
361016ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
361198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#endif
3612cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36134eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
361416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageProperty(image,"png:tRNS                 ",msg,
361516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36164eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36174eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
361898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_sRGB != MagickFalse)
36194eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
36203b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
362198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            "intent=%d (%s)",
362298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            (int) intent,
362398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            Magick_RenderingIntentString_from_PNG_RenderingIntent(intent));
362416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:sRGB                 ",msg,
362598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp                 exception);
36264eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
36274eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
36284eb3931feb349dd87142c78503b779228f3e1a0fglennrp
362998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_gAMA != MagickFalse)
36304eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
36313b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
363216ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
363316ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
363416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:gAMA                 ",msg,
363516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36364eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3637cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36384eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3639cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
36404eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
36413b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
364207523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
36434eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
364416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:pHYs                 ",msg,
364516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36464eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
36474eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3648cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36494eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
36504eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
36514eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
36523b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
36534eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
365416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:oFFs                 ",msg,
365516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36564eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
36574eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
36584eb3931feb349dd87142c78503b779228f3e1a0fglennrp
365907523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
366007523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
366107523c7d2e40370804c2036295571e4b6426f94dglennrp       {
36623b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
366307523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
366407523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
366516ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:vpAg                 ",msg,
366616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
366707523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3668cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3669cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3675cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
36800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3681edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
3682edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
3683edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
3684edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3685edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* }  for navigation to beginning of SETJMP-protected block, revert to
3686edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    Throwing an Exception when an error occurs.
3687edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
3688edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
370121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
370221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
371947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
372347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3726fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
372716ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
373047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
373347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
373847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3739dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
374147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
374673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
374747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
375047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
376147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
37680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
37760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
377947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
378147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
37870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
379047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
379172715f5c299a6482f8eb175070b056d77b74a43fcristy  if ((IssRGBColorspace(image->colorspace) != MagickFalse) &&
3792a8036d6466b63ead629795b60772f160cca77c4cglennrp      ((image->gamma < .45) || (image->gamma > .46)))
379372715f5c299a6482f8eb175070b056d77b74a43fcristy    SetImageColorspace(image,RGBColorspace,exception);
379472715f5c299a6482f8eb175070b056d77b74a43fcristy
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
379716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(image,TrueColorType,exception);
37988a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
380216ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) SetImageType(image,TrueColorMatteType,exception);
38030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
380597f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
380697f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
380797f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
380897f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
380997f90e23c85b9c58387880125c29d8c99126f83aglennrp
381097f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
38120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38644383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
38654383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
38664383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3867bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
388716ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3890bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
389416ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3905bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3919fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
39220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
392316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
39310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
393216ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
39330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
39360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
39640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
39670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3975e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3976e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
39800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
398347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
39870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3991bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
39930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
399647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
400347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4011bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
4013bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
401947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
402247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
402747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4031f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
403247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4034f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
403547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
403847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
404247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
404647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
405047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
405447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
405847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
406247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
406847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
407147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
408773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
408847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
409147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
409316ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
40940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
41010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
41050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
411273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
41130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
411816ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
41190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
41300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
41340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
41370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
41460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
41490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
415203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
416947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
417647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
417947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
418847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4196bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
419803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
421347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
42330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
42638182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
42640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42738182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
42748182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
42758182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
42768182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
42778182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
42788182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
42798182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
42808182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
428247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4291e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4292cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
4293da7803d6b1161960bc1e7db4d9718284c116fab8cristy            image->gamma=1.000f/2.200f;
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
430347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43125eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
43135eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
43140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
432147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
433216ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
433316ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
433716ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
433816ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4349fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
43620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
438516ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
439147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
43950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43963b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
43980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
44010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
44150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
44180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4419bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
442116ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
442316ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
442416ea139d53d867211d3bb0fa859a83de653f687ecristy    {
442516ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
442616ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
442716ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
442816ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
442916ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
443016ea139d53d867211d3bb0fa859a83de653f687ecristy    }
443147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
44350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
44370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
444803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
44520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
44540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
445716ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44593b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
44630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4465bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
446816ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
447047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44718a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             if (image->alpha_trait == BlendPixelTrait)
447216ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
447316ea139d53d867211d3bb0fa859a83de653f687ecristy               {
447416ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
447516ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
447616ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
447716ea139d53d867211d3bb0fa859a83de653f687ecristy               }
44780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
448016ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
448216ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
448316ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
44848a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->alpha_trait=BlendPixelTrait;
448516ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
448616ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
44880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
450047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
450147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
45070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
45090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
45100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
45110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
45120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
45130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
45150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
45160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
45170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
45180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
45190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
45210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
45220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
45230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
45240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
45280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
45320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
457421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
457521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4595fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
459616ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
45990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
46050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
460647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
460747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
460947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46103b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
46120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
461347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
461447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
461673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
46170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
46200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
462147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
462247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
46300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
46380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
46420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
464647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
46520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
46550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
46580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46724383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
467321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
467421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
46754383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4682bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
470016ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4730bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
473938ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
474038ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
474138ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4742bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
476447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
476547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4771fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
477216ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
47750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
47780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
478247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
478347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
478447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
478573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
47860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
47890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
479047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
479147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
480147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
480547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
480647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4810bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
481447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4857e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4858e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
48620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
48650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
48680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
487247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
487547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
487847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
48880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
489016ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
48920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
48990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
490116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
49030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
490847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
49130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
49200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4926bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
49280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4929bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
49310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4935e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4937e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
49418182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
49420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
49450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
49490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
49520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
49568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
49600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
49630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
49660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
497116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
497347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
497416ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
49750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
49780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
49860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49873b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy            (void) FormatLocaleString(page_geometry,MaxTextExtent,
4988e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4989f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
49900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4992bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4994bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
49960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
49990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
50120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50158182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
50168182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
50170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
50200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
50290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5031e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
50320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5034e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
504316ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
50460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
50480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
505016ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
50530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
5057edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  Instead of using a warning we should allocate a larger
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
506016ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
506916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
50770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
50800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
50870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
50880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
50900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
50910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5095e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
5096f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
50970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5099e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
5100f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
51100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
51170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
51220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
51250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
51280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
51400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
51430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
51480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
51510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
51540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
515516ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
516647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
516947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
517047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
51760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5177bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
518435ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
51930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
51990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
520347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5209bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
521612560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5224bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52278182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
52340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
524147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
524247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
52468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
52478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
52498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
52518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
52538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
52558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
52578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
526247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
526647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5274e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5275cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
528047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
528447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5287fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
529447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
529747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
530116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
53040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
53070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
531147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
53150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
53190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
532247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
532347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
532547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5326bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
532847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
533047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5331bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
534247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
53468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
53470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53488182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
53498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
53500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5351bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5352bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
53530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
53560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
53580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5361e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
536347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5366bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5367bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
53680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5369bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5370bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
53710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5372bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5373bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
53740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
53770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
53790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5382e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
538447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
53900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5394e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5395e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
539647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
54040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5405bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
54070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5408bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5416e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5417e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
54180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
542247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
542316ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
542516ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
542647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
543347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
54380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
54480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
54568a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                image->alpha_trait=UndefinedPixelTrait;
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
545816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
54590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5463e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5464e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
548147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
549347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
551747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
551847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5527bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5530bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
554247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5545bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
554947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
555047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5553bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
557047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5577bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
558047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
558147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
55828182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
55830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5586e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5587e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
55880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
55910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
560247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
560647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
561847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
56250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5629e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5630f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
563147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
56360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
564147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
565947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
566347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
566716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
567047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
567347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
56900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
56930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
56960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
570316ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
570747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
571347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
571947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
572247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
572847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
573147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
573747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
574047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
574647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
574947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
575547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
575847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
576447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
576747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
577347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
577747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
578116ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
578547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
580447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
580816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
581147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
581447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
581816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
582147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
582447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
582947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
58458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
58478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
585147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
585816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
586047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
586647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
586816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
587147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5874bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
588447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
588747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
589047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
589347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
589647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
589947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
590247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
591047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
591347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
591647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
592147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
593147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
593847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
594147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
594747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
595547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
59578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5970bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5972bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
597416ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
597916ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
598047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
598747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
599147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
599847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
600147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
600247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
600347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
601216ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6015e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
6016e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
602716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
603216ea139d53d867211d3bb0fa859a83de653f687ecristy              AcquireNextImage(image_info,image,exception);
603347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
604047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
60430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
60450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
605547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
60648a46d827a124555f0c48fb2368ec1bba8e079ab6cristy            image->alpha_trait=UndefinedPixelTrait;
606516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
60660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6070e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6071e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
607547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
607616ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
608116ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
608247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
608947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
60950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
60980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
61070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
61160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
612247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
612647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
613147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6132bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
613347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
614547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
615847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
619147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
619447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
619647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
619747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
619947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62024e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
620347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
620647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
620947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
621147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
621247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
621447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
621847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
622147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
622347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
622447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
622647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62294e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
623047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
623347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
623647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
623847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
623947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
624147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
625116ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
625216ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
625316ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
625416ea139d53d867211d3bb0fa859a83de653f687ecristy
625516ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
625616ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
625716ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
625816ea139d53d867211d3bb0fa859a83de653f687ecristy
6259bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
626316ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
626716ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
626816ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
627047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
627147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
627547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
627616ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
627747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62933faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6301bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
630547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6306bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
630816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
630916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
631016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
631116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
631216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
631316ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
631416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
631516ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
631616ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
631847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63278a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                if (image->alpha_trait == BlendPixelTrait)
632816ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
632947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
633216ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
633316ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
633447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
633747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
634047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
634347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6352e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6353bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
635516ea139d53d867211d3bb0fa859a83de653f687ecristy                length=(size_t) image->columns*GetPixelChannels(image);
635616ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
635716ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
635847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
635916ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
636016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
636747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
637047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6371bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6374bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
637547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6376bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6377bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
637847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6379bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
638147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6382bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
638447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6386bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
638747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
639147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6392bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
639847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
640116ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6404bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
64089fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
640916ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
641016ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
641147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6412bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6414fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6423bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
642416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
642516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
642616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
642716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
642816ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
642916ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
643016ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
643247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6436bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
643716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
643816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
643916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
644016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
644116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
644216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
644316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
644416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6445bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
644647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
645016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
645116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
645216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6453bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
645416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
645516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
645616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
645716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6458bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
645916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
646016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
646116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
646216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6463bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
646416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
646547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64668a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                              if (image->alpha_trait == BlendPixelTrait)
646716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
646816ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
646916ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6470bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
647116ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
647347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
647816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
647916ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
648116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
648216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
648547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6490bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
649116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
649216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
649316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
649416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
649516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
649616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
649716ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
649816ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6499bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
650047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6502bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
650316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
650416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
650516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
650616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
650716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
650816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
650916ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6510bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
651147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
651416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
651516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
651616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6517bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
651816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
652116ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
652216ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
652316ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
652547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
652847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
653147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
653216ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
653316ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6550e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6552bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
655416ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
655816ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
655916ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
656047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6562bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
656416ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
65657c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6566bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6567bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
656847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6569bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6570bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
657147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6572bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6573bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
657447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6575bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
657747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6579bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
658047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
658616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
658716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
658816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
658916ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
659147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6595bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
659616ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
659716ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
659816ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
659916ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6600bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
660147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
660216ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
660616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
660716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
660816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6609bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
661016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6611bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
661216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
661316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
661416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6615bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
661616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6617bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
661816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
661916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
662016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6621bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
662216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
66238a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                              if (image->alpha_trait == BlendPixelTrait)
662416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
662516ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
662616ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6627bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
662816ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
663047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6635bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
663616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
663716ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6638bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6640bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
664116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
664216ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6643bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
664647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6651bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
665216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
665316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
665416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
665516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6656bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
665747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6659bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
666016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
666116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
666216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
666316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6664bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
666547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
666916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
667016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
667116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6672bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
667316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
667616ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
667816ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
667916ea139d53d867211d3bb0fa859a83de653f687ecristy                    p+=GetPixelChannels(image);
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
668147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
66853faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6691bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
669447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6695bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
669716ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
669816ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
669916ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
670016ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
670116ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
670216ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
670316ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
670416ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
670516ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
670747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
674147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6757bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6758bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
676447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
677647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
678716ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
68002b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
680116ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
68022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
68032b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
68042b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
68052b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
68062b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
68073faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
6808cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
6809cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
6810cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
6811cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
6812cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
6813cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
681416ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
68158640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6817d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6821bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6824d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6828d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
683047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
683247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
683647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
68470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
684816ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
685316ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
685847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
686247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
68703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
68748a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
68750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
687716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
68780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
68830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
68860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
689447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
689516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
689847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
69030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
690847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
690916ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
691447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
692247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
692316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
692747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
693347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
693416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
693647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
693947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
69470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
69500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
69530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
695847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
69640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
69660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6969e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6970e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
69710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
697947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
698247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6984e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
698547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6990e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7002bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
700747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
700916ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
701047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
701347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
701647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
702547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
702847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
704547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
705547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
705847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7060e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
7061e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
706247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7064f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7065f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
706647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7067f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7068e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7069e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7070f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7071f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
707247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
707647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
707947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
708225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
708747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
709047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
709347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
709825c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
71153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7121bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7124bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
713747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
714347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
715147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
715547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
716347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
716647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
717147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
717447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
717747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
718347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
718847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
719347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
719647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
720147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
720647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
721647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
722047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
722747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
723047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
723547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
724347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
724847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
725647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
726347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
727047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7271edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
7272cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
727318b17443128598500357da7bff2f01683cf32890cristy#endif
727447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
730547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7306edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
7307cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
7308cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
731325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
733216ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
733316ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
734116ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7391cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7398bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
74190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
74200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
74220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7423a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
7424a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
7425a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7426a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
7427a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
7431a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
7432a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping,
7433a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy      (png_alloc_size_t) allocated_length);
7434a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
7435a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7436a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
7437a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
7438a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
74503b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7451f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
745347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7454bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
74573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
746147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
74653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
746847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
747147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7477cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
74784383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
74793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
74903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
749247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
749347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
749447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
749647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7500cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
750247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
750347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
750447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
750547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
750647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
750747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7508cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7509cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7510cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
751147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
751247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
751347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
751447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
751547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
751647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
751747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7518cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
751947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
752147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
752447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7528b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7529b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
753116ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
753316ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
753416ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
753516ea139d53d867211d3bb0fa859a83de653f687ecristy
753616ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
753716ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
753816ea139d53d867211d3bb0fa859a83de653f687ecristy
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7552cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7553cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7554e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7555e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
75565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
755739992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
755839992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
75615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
75625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
75635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
75715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
75725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
75735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7574bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
757858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
757921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
758058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
758158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7582da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7583fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7584d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
75858d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
758639992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7587991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7588991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7589991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
759026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
759126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
759226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7593a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7594e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
759526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
759626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
759726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
759826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
759926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
760026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
760126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7602e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
760326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
760426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
760526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
760626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
76078d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
76080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
76090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
761082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
76118ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7612d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7613d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
761816ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
761916ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
762016ea139d53d867211d3bb0fa859a83de653f687ecristy
7621bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
762675fc68f33e6e766a22e8ed653c3ed50b0d142827cristy    *volatile ping_pixels;
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7629f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
76300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
76315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
76325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
76335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
76345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
76355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
76365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7637bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
76385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
76395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7641bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7646dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7647fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7648f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
76498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
76508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
76518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7652dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7653dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7654dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7655dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7656dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7657dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7659fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
766116ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
766216ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
766316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
766416ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7665b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
76665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
76670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
76685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
76695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
76705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
76715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
76725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
76735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
76745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
76755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
76765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
76775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
76785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
76795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
76805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
76815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
76825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
76835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
76845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7685dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
7686dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
7687dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
7688dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7689da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
7690d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
76918d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
769239992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
7693991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
7694991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
7695991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
7696991d11dd9c33e65872778b81aff1347cd2878154glennrp
76970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
76980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
7699a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
7700dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
77010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
77020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
77030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
77040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
77050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
77060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
77070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7708dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
77090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
77100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
77110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
77120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
77138d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
77140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
77150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
77160d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
77170d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
77180d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
77190d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
77200d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
77210d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
77220d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   if (ping_exclude_sRGB == MagickFalse)
77230d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
77240d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
77250d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
77260d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
77270d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
77280d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
77290d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
77300d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
77310d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
77320d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
77330d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
77340d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
77350d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
77360d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
77370d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
773816ea139d53d867211d3bb0fa859a83de653f687ecristy               (LocaleCompare(name,"ICM") == 0))
773916ea139d53d867211d3bb0fa859a83de653f687ecristy              {
7740ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
7741ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   icheck;
77420d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7743ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 /* 0: not a known sRGB profile
7744ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 1: HP-Microsoft sRGB v2
7745ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 2: ICC sRGB v4 perceptual
7746ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 3: ICC sRGB v2 perceptual no black-compensation
7747ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  */
77480d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 png_uint_32
7749ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   check_crc[4] = {0, 0xf29e526dUL, 0xbbef7812UL, 0x427ebb21UL},
7750ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   check_len[4] = {0, 3144, 60960, 3052};
77510d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7752ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
7753ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
7754ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   profile_crc;
775529a106ed9ec29e243521b0f2a26c14281de8347fglennrp
7756ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
7757ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
77580d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7759ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
776029a106ed9ec29e243521b0f2a26c14281de8347fglennrp
7761ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 for (icheck=3; icheck > 0; icheck--)
776229a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
7763ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   if (length == check_len[icheck])
7764ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
7765ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7766ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
7767ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
77680d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7769ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     data=GetStringInfoDatum(profile);
7770ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     profile_crc=crc32(0,data,length);
77710d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7772ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7773e54cd4b9aa386137b617b4b7fc66436c70466007glennrp                         "      with crc=%8x",(unsigned int) profile_crc);
7774ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
7775ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     if (profile_crc == check_crc[icheck])
7776ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
7777ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7778ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                            "      It is sRGB.");
7779ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
7780ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                          image->rendering_intent=PerceptualIntent;
7781ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
7782ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
778329a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
77840d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
7785ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 if (icheck == 0)
778629a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7787ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        "    Got a %lu-byte ICC profile",
778829a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
778929a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
77900d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
77910d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
77920d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
77930d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
77940d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
77958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
77968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
77978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
77988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7799fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
7800fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7801fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
7802fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7803fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
7804fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
7805fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7806fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
7807fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
7808fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7809fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
7810fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
781128af3713c9111a471cc868c787760de89236fa3cglennrp
7812750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  if (image->storage_class == PseudoClass &&
78137e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
78147e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png_colortype != 0 &&
78157e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     mng_info->write_png_colortype != 4)))
78167e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
781716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
78187e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
78197e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
78207e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
7821c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
782228af3713c9111a471cc868c787760de89236fa3cglennrp    {
7823c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
7824c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
7825c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
7826c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
7827c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7828c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
7829e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
7830c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
7831c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
783228af3713c9111a471cc868c787760de89236fa3cglennrp    }
7833bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
78343d9f5ba107b160e1819bb6baeeb3a9f521e9f450cristy  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
783516ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
78360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78373241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
78383241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
78393241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
78403241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
78413241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
784216ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
78433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7844a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
7845a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
7846a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
7847a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
7848a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7849a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
7850a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7851a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
7852a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
7853a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
7854a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
78558e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
785667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < MAGICKCORE_QUANTUM_DEPTH)
785767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
785816ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
78598e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
78608e58efdecda887b08ef730d68290a61081ef2566glennrp
78618e58efdecda887b08ef730d68290a61081ef2566glennrp       if (image->depth > 8)
78628e58efdecda887b08ef730d68290a61081ef2566glennrp         {
78638e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 16
78648e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 16-bit */
786591d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR16PacketRGBO(image->background_color);
78668e58efdecda887b08ef730d68290a61081ef2566glennrp
78678e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
78688e58efdecda887b08ef730d68290a61081ef2566glennrp           {
786916ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
78708e58efdecda887b08ef730d68290a61081ef2566glennrp
787116ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
78728e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
78738e58efdecda887b08ef730d68290a61081ef2566glennrp
78748e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
78758e58efdecda887b08ef730d68290a61081ef2566glennrp             {
787616ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR16PixelRGBA(r);
787716ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
78788e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7879bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
78808e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
78818e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
78828e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78838e58efdecda887b08ef730d68290a61081ef2566glennrp
78848e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
78858e58efdecda887b08ef730d68290a61081ef2566glennrp           {
78863e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
78878e58efdecda887b08ef730d68290a61081ef2566glennrp             {
788891d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR16PacketRGBO(image->colormap[i]);
78898e58efdecda887b08ef730d68290a61081ef2566glennrp             }
78908e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78918e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 16 */
78928e58efdecda887b08ef730d68290a61081ef2566glennrp         }
78938e58efdecda887b08ef730d68290a61081ef2566glennrp
78948e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 4)
78958e58efdecda887b08ef730d68290a61081ef2566glennrp         {
78968e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 8
78978e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 8-bit */
789891d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR08PacketRGBO(image->background_color);
78998e58efdecda887b08ef730d68290a61081ef2566glennrp
79008e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
79018e58efdecda887b08ef730d68290a61081ef2566glennrp           {
790216ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79038e58efdecda887b08ef730d68290a61081ef2566glennrp
790416ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79058e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79068e58efdecda887b08ef730d68290a61081ef2566glennrp
79078e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
79088e58efdecda887b08ef730d68290a61081ef2566glennrp             {
790916ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR08PixelRGBA(r);
791016ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
79118e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7912bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
79138e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
79148e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
79158e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79168e58efdecda887b08ef730d68290a61081ef2566glennrp
79178e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
79188e58efdecda887b08ef730d68290a61081ef2566glennrp           {
79193e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
79208e58efdecda887b08ef730d68290a61081ef2566glennrp             {
792191d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR08PacketRGBO(image->colormap[i]);
79228e58efdecda887b08ef730d68290a61081ef2566glennrp             }
79238e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79248e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 8 */
79258e58efdecda887b08ef730d68290a61081ef2566glennrp         }
79268e58efdecda887b08ef730d68290a61081ef2566glennrp       else
79278e58efdecda887b08ef730d68290a61081ef2566glennrp         if (image->depth > 2)
79288e58efdecda887b08ef730d68290a61081ef2566glennrp         {
79298e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
793091d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
79318e58efdecda887b08ef730d68290a61081ef2566glennrp
79328e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
79338e58efdecda887b08ef730d68290a61081ef2566glennrp           {
793416ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79358e58efdecda887b08ef730d68290a61081ef2566glennrp
793616ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79378e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79388e58efdecda887b08ef730d68290a61081ef2566glennrp
79398e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
79408e58efdecda887b08ef730d68290a61081ef2566glennrp             {
794116ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
794216ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
79438e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7944bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
79458e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
79468e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
79478e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79488e58efdecda887b08ef730d68290a61081ef2566glennrp
79498e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
79508e58efdecda887b08ef730d68290a61081ef2566glennrp           {
79513e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
79528e58efdecda887b08ef730d68290a61081ef2566glennrp             {
795391d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
79548e58efdecda887b08ef730d68290a61081ef2566glennrp             }
79558e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79568e58efdecda887b08ef730d68290a61081ef2566glennrp         }
79578e58efdecda887b08ef730d68290a61081ef2566glennrp
79588e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
79598e58efdecda887b08ef730d68290a61081ef2566glennrp         {
79608e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
796191d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
79628e58efdecda887b08ef730d68290a61081ef2566glennrp
79638e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
79648e58efdecda887b08ef730d68290a61081ef2566glennrp           {
796516ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79668e58efdecda887b08ef730d68290a61081ef2566glennrp
796716ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79688e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79698e58efdecda887b08ef730d68290a61081ef2566glennrp
79708e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
79718e58efdecda887b08ef730d68290a61081ef2566glennrp             {
797216ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
797316ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
79748e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7975bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
79768e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
79778e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
79788e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79798e58efdecda887b08ef730d68290a61081ef2566glennrp
79808e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
79818e58efdecda887b08ef730d68290a61081ef2566glennrp           {
79823e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
79838e58efdecda887b08ef730d68290a61081ef2566glennrp             {
798491d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
79858e58efdecda887b08ef730d68290a61081ef2566glennrp             }
79868e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79878e58efdecda887b08ef730d68290a61081ef2566glennrp         }
79888e58efdecda887b08ef730d68290a61081ef2566glennrp       else
79898e58efdecda887b08ef730d68290a61081ef2566glennrp         {
79908e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
799191d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
79928e58efdecda887b08ef730d68290a61081ef2566glennrp
79938e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
79948e58efdecda887b08ef730d68290a61081ef2566glennrp           {
799516ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79968e58efdecda887b08ef730d68290a61081ef2566glennrp
799716ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79988e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79998e58efdecda887b08ef730d68290a61081ef2566glennrp
80008e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
80018e58efdecda887b08ef730d68290a61081ef2566glennrp             {
800216ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
800316ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
80048e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8005bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
80068e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
80078e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
80088e58efdecda887b08ef730d68290a61081ef2566glennrp           }
80098e58efdecda887b08ef730d68290a61081ef2566glennrp
80108e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
80118e58efdecda887b08ef730d68290a61081ef2566glennrp           {
80123e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
80138e58efdecda887b08ef730d68290a61081ef2566glennrp             {
801491d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
80158e58efdecda887b08ef730d68290a61081ef2566glennrp             }
80168e58efdecda887b08ef730d68290a61081ef2566glennrp           }
80178e58efdecda887b08ef730d68290a61081ef2566glennrp         }
8018cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
8019cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
802067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
802167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
802270e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
8023a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
80242b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
80252b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
80262b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
80272b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
80288e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
80292b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
80302b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
80312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
80323faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
8033cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
8034cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
8035cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
8036cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
8037cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
8038cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
8039c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
804016ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
80418640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
80428640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
80438640fb5e9b1094f35f8beab436f81661b8a99448glennrp
8044a8036d6466b63ead629795b60772f160cca77c4cglennrp  if (image->storage_class != PseudoClass && mng_info->write_png_colortype &&
8045a8036d6466b63ead629795b60772f160cca77c4cglennrp     (mng_info->write_png_colortype > 4 || (mng_info->write_png_depth >= 8 &&
8046a8036d6466b63ead629795b60772f160cca77c4cglennrp     mng_info->write_png_colortype < 4 &&
8047a8036d6466b63ead629795b60772f160cca77c4cglennrp     image->alpha_trait != BlendPixelTrait)))
8048a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8049a8036d6466b63ead629795b60772f160cca77c4cglennrp     /* Avoid the expensive BUILD_PALETTE operation if we're sure that we
8050a8036d6466b63ead629795b60772f160cca77c4cglennrp      * are not going to need the result.
8051a8036d6466b63ead629795b60772f160cca77c4cglennrp      */
8052a8036d6466b63ead629795b60772f160cca77c4cglennrp     image_colors=image->colors;
8053a8036d6466b63ead629795b60772f160cca77c4cglennrp     number_opaque = image->colors;
8054a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (mng_info->write_png_colortype == 1 ||
8055a8036d6466b63ead629795b60772f160cca77c4cglennrp        mng_info->write_png_colortype == 5)
8056a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickFalse;
8057a8036d6466b63ead629795b60772f160cca77c4cglennrp     else
8058a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickTrue;
8059a8036d6466b63ead629795b60772f160cca77c4cglennrp     ping_have_non_bw=MagickFalse;
8060a8036d6466b63ead629795b60772f160cca77c4cglennrp
8061a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (image->alpha_trait == BlendPixelTrait)
8062a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8063a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 2;
8064a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 1;
8065a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8066a8036d6466b63ead629795b60772f160cca77c4cglennrp
8067a8036d6466b63ead629795b60772f160cca77c4cglennrp     else
8068a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8069a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 0;
8070a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 0;
8071a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8072a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
8073a8036d6466b63ead629795b60772f160cca77c4cglennrp
8074a8036d6466b63ead629795b60772f160cca77c4cglennrp  else
8075a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8076a8036d6466b63ead629795b60772f160cca77c4cglennrp  /* BUILD_PALETTE
8077a8036d6466b63ead629795b60772f160cca77c4cglennrp   *
8078a8036d6466b63ead629795b60772f160cca77c4cglennrp   * Normally we run this just once, but in the case of writing PNG8
8079e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
8080e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
80818ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
80828ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
80838ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
80848ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
8085c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
808682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
80878ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
808882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
8089d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
809082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
80918ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
8092d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
8093a8036d6466b63ead629795b60772f160cca77c4cglennrp    /*
8094d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
8095d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
8096d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8097d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
8098d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
8099d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
8100d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8101d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8102d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
81038a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     * If image->alpha_trait is MagickFalse, we ignore the alpha channel
8104d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8105d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8106d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8107d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8108d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8109d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8110d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8111d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8112d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
81133c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8114d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8115d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
81168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
811716ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8118d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8119d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8120d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
81218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
812216ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
812316ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8124d6bf1617e99df0272b231855a933a74e99b6578fglennrp
812516ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
812616ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8127fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8128fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8129d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8130d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8131d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8132d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8133d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8134d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8135d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8136d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8137d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8138d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8139d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81408a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             "      image->alpha_trait=%.20g",(double) image->alpha_trait);
814103812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8142d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
81433c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8144fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
81457ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
81467ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8147d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
81488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
814916ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
81502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8151d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
81527ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8153d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8154d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8155d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8156d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8157d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8158d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
815916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
81607ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
81612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8162d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8163d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8164d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8165d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8166d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8169d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8170d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8171d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
817216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8173d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8174d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8175d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
81762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8177d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8178d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
817983c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8180d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
818116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
818216ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
81837ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
81848d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
81858d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81868d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8187d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
81887ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8189d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8190fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8191fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8192fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
81932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8194d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8195d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8196d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
81977ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
819816ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8199d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
820097fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8201d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8202d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
82038a46d827a124555f0c48fb2368ec1bba8e079ab6cristy           if (image->alpha_trait != BlendPixelTrait ||
820416ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
82058d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8206d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
82078d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8208d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8209d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
821016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
821116ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8212d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8213d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8214d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8215d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8216d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
821716ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, opaque+i))
8218d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8219d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8220d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
822116ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8222d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8223d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
822416ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
822516ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8226d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
82278d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
82288d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
822916ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
82308d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8231d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
82328d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8233d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8234d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
823516ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
823616ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
823716ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
823816ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
823916ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
824016ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
824116ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
824216ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
8243972d1c4895c4ee6da1b6745e1bb9cb71ee5d6d08cristy                         GetPixelGray(image,q);
8244d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8245d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8246d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8247d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8248d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
824916ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, transparent+i))
8250d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8251d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8252d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8253d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8254d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8255d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8256d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
825716ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
82598d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
82608d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8261d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8262d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8263d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8264d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8265d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8266d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
826716ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8268d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8269d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
82708d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8271d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8272d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
827316ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
827416ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
827516ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8276d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8277d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8278d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8279d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8280d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8281d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8282d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
828316ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8284d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8285d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
82868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
828716ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8288d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8289d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
82903c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
82914054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
82924054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8293d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8294d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8295d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8296d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8297c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8298c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8299c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8300c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8301c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8302c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8303c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8304c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8305d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8306d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8307ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8308ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8309ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8310ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8311d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8312d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
831303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
83148e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8315c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8316388a8c871db8f82488f34c4f41fc64a58b8cfbf7glennrp               number_opaque++;
8317c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8318c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8319c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8320c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8321c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8322c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
832303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8324a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8325a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8326a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8327d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
83282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8329d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
83303241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8331a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
8332a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
8333a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
8334a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
8335a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
8336a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
8337a080bc32a4a8b2ffec83fd836a28753959175363glennrp
8338d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8339d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8341d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8342d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
83433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8344d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8345d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8346d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8347d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
83483241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
83498d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
83508d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
83518d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8352fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8353d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8354d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
83550fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         ping_have_non_bw=MagickFalse;
83560fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
83573fcfa950eeb4614ffea1dba94a68569bb4491dedglennrp         if ((IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) &&
83583fcfa950eeb4614ffea1dba94a68569bb4491dedglennrp             (IssRGBColorspace(image->colorspace) == MagickFalse))
83590fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
83607fb2652ba366fc984d1dbb0c66560b91c57dab78cristy           ping_have_color=MagickTrue;
83610fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp           ping_have_non_bw=MagickFalse;
83620fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
83630fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
8364d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8365d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8366d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8367d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8368d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83696185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
837016ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8371d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
83726185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8373e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8374e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8375e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
837616ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
837716ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8378e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8379e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8380e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8381e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8382e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
838316ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8384e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8385e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8386e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8387e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8388e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8389d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8390d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8391d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
83926185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8393d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8394d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8395d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8396d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
83976185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
839816ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
839916ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8400d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8401d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8402e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8403d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
840416ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8406e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8408bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8409bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
84104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
841316ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8415bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8416d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8419d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8420d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8423d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8425d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
84273241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
84303241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8433d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8435d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8437c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8438c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8439bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8441d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8443d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8447d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8453d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8454d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8455d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8456d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8457d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
84623241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
84706185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8473d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8474d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
84752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8478d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8479d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
848216ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
84843faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
84853faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8488d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8489d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8492d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8493d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8495bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8499d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8500fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8501fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8502d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
850416ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
85053c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
850616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8507d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
85083c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8510d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8511d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
851203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
85138a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                  if ((image->alpha_trait != BlendPixelTrait ||
851416ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
851516ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
851616ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
851716ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
85186185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
851916ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8520d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
85216185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
852203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
852316ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8524d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8527d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8528d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8530d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8531d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8532d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8534d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8535d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8536d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8537d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8538d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
854016ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
854183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8542d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
854472988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8545d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8547d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8548d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8549d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8550d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
855216ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
85546185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
85556185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
85563c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8558d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8561d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
85623c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
85653c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8566d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8567d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8568d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8569d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
857003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8571d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8572d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8573d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
85746185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8576d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8577d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8578d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
85796185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8580d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8581d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8582d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8583a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8585d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8586d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8587a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8588d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8589d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8590d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8592d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8593d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8594d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
85956185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
859603812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
859703812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8598d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
85993c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8600c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8601c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8602fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8603c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8604c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8605c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8606c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8607c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8608c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8609fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8610c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8611130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8612130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8613130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8614c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8615130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8616c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8617c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8618c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8619fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8620c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8621c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
862216ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8623fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
862416ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8625c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8626fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8627c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8628c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
862916ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
86308ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
863116ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelInfoPixel(image,&image->background_color,r);
863216ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
86338ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
86348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
863516ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
863616ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8637c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8638bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8639c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8640c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8641fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8642c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8643c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8644c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
864516ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
864616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
864716ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
8648c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8649c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8650c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8651c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8652c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8653e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8654e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8655e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8656c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8657d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8658d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8659d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8660d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8661d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8662d337164012450d70d62e71cf4a308a29004f7d57glennrp
8663d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8664d337164012450d70d62e71cf4a308a29004f7d57glennrp
866591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8666d337164012450d70d62e71cf4a308a29004f7d57glennrp
8667d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8668d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8669d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8670d337164012450d70d62e71cf4a308a29004f7d57glennrp
8671d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8672d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8673d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8674d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
867516ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8676d337164012450d70d62e71cf4a308a29004f7d57glennrp
867716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8678d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
8679d337164012450d70d62e71cf4a308a29004f7d57glennrp
8680d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
8681d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
868216ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
868354cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
868416ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8685d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
8686bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8687d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8688d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
8689d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8690d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8691d337164012450d70d62e71cf4a308a29004f7d57glennrp
8692d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
8693d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
8694d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8695d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
8696d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8697d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
86988e58efdecda887b08ef730d68290a61081ef2566glennrp
8699d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
8700d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
870191d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
8702d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8703d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8704d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
8705d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
8706d337164012450d70d62e71cf4a308a29004f7d57glennrp
870782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
870882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
870982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
871082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
871182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
871282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
871382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
871482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
871591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
871682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
871782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
871882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8719e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
872082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
872182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
872282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
872382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
872482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
872516ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
872682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
872716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
872882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
872982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
873082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
873182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
873216ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
873316ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
873416ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
873582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
8736bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
873782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
873882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
873982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
874082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
874182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
874282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
874382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
874482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
874582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
874682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8747e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
874882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
874982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
875091d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
875182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
8752d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8753d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
875482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
8755c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
87568ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
8757c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8758c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
8759c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8760c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
8761c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
87628ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
87638ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
87643faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
87653faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
87663faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
87673faa9a3fb01696daaf976d595f492cb530bffb21glennrp
876891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
8769fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8770c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
8771c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8772e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
8773fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8774c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
8775c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8776c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
8777c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
877816ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
87798d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
878016ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8781c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
8782c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8783c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
8784c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
878516ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
878654cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
878716ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8788c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
8789bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8790c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8791c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
8792c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8793c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8794c722dd852e8abe407c2846d39662f7ade9c234deglennrp
8795c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
8796c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
8797c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8798c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
8799c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8800e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
8801c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
8802c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
880391d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
8804c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8805c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
8806c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8807c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8808c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
88098ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
88108ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
88118ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
88128ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      /* Take care of special case with 256 colors + 1 transparent
88138ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
88148ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
88158ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
88168ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
88178ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
88188ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
88198ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
88208ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
88218ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
88228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
8823bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
88248ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
88258ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
88268ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
88278ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
882816ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8829bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
883016ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
88318ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
8832bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
88338ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
88348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
883516ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
883616ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
883716ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
883816ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
88398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
884016ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
88418ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
884216ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
88438ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
8844bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
88458ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
88468ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
8847bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
88488ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
88498ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
88508ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
88518ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
88528ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
88538ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
88548ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
88558ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
88568ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
88578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
88588ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
88598ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
88608ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
88618ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
88628ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
88638ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
8864fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
8865a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
8866fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
8867fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8868fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
8869fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
8870fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
8871fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
88720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
88730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
88740e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
8875d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
88760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
88770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
88780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
88790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
88800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
88810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
88820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
88838d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
8884d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
88850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
88860b206f5daa453dc1035db5890cabc899736dc2d0glennrp
88870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
88880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
8889fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
8890fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
8891fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
88925a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
88935a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
88945a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
8895fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
88965a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
88975a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
8898fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8899fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
8900fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8901fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
8902fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
8903fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8904fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
8905fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
8906fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
890716ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
8908fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
8909fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8910fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
8911fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
8912fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
8913fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
891416ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
8915fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
8916fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8917fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
8918fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
891916ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
892016ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
892116ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
892216ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
892316ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
892416ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
892516ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
8926fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
8927fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8928fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8929fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
8930fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
893116ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
8932fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
8933bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8934fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
8935fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
8936fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
8937fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8938fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
8939fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
894067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
894167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
894267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
8943fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
894467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
894567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
894667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
894767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
8948fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
894967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
895067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
8951fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
8952fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8953bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8954fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
8955fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8956fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
8957fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8958fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
8959fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8960fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
8961fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8962fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
8963fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8964fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
8965fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
8966fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
8967fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
89683c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
89693c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
89703c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
89713c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
8972f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
8973b0a657e13c4aefba39c51292005427b47277869dcristy  image_matte=image->alpha_trait == BlendPixelTrait ? MagickTrue : MagickFalse;
897483c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
89750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
89761273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
897852a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
897952a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
898052a479ca718756af72f96e127f8256499ab68f76glennrp    {
898116ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
898216ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
898316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
898415e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
898516ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
898652a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
898752a479ca718756af72f96e127f8256499ab68f76glennrp    }
898852a479ca718756af72f96e127f8256499ab68f76glennrp
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
899316ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
899416ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
899516ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
8996cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
8997cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
89980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
900016ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
9001cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
90020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
90060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
90080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
90133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
9016cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
9028edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
9029cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9031edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9032edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (ping_pixels != (unsigned char *) NULL)
9033edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
9034edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9035edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (quantum_info != (QuantumInfo *) NULL)
9036edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        quantum_info=DestroyQuantumInfo(quantum_info);
9037edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
903816ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
903916ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
904016ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
904116ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9044edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9045edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
9046edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
9047edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
9048edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
9049edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9050edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
9051edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
9052edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
9053edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90579bf97b6c2143eb20c330346b01e82102cc082725glennrp
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
906025024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  {
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
906225024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
906325024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     /* Disable new libpng-1.5.10 feature when writing a MNG because
906425024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      * zero-length PLTE is OK
906525024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      */
906625024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     png_set_check_for_invalid_index (ping, 0);
906725024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# endif
906825024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  }
90692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
90742b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90772b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
90792b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90804e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
90814e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
90822b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
90850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
90880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
90920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
90950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
90980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9102e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9104e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91068a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        "    image_matte=%.20g",(double) image->alpha_trait);
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91088640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91108640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91128640fb5e9b1094f35f8beab436f81661b8a99448glennrp
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
91145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
9115dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
911626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
911826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
911926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
912016ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
9124dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9125dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9129dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
9130823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
913116ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
9132823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
913316ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9135dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9138dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
913916ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
914016ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9142991d11dd9c33e65872778b81aff1347cd2878154glennrp
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9145dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
914616ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
914716ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9149991d11dd9c33e65872778b81aff1347cd2878154glennrp
9150823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9151823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9152823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9153823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9154823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9155991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
915726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9159a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
916026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
916126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9162a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9164a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9165a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9166a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9167a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9168a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9169a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
91700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9171a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9172a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
91730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9174a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9175a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
91760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9177a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9178a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
91790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9180a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9181a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
91820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9183a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9184a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
91850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9186a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9187a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9188c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9189c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
91900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
91910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
91933b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
91943b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91953b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9196c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9197c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9198c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
91993b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
92003b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92013b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
92023b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
92030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
920526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
92120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92131273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9216fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
92170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
92180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
92208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
92218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
92220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
92240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
92250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
92260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
92270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
92290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9231f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
92320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
92340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
92350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
92360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
92370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
92380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
92390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
924067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
92410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
924267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
924367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
924467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
92450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
92482b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
92498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
92508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
92518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
92525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
925358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
92548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
92550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
92560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
92570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
92580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
92598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
92628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
92630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92652cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
92668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
92670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
92690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
92700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
92728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
92738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
92740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92751273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
92764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
92771273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
92781273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
92791273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
92801273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
92814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
92824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
92834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
92840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9286c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9287c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9288c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9289c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9290c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9291c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9292c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
92934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
92950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92967e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  else if (mng_info->write_png24 || mng_info->write_png_colortype == 3)
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
92995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93027e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  else if (mng_info->write_png32 || mng_info->write_png_colortype == 7)
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
93055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
93110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
93145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
93150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
93175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
93192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
93208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
93218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
93227c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
93237c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
93247c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93257c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
93270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93287c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93323c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
93330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9334d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
93358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
93360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9337d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
93395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
93420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9343d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
93455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
93480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93495aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
93505aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
93515aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
93525aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
93537c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
93547c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
93557c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
93575aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
93588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
93595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
93605aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
93615aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
93625aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
93635aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
93640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93650b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
93665aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
93675aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
93685aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
93695aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
93708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
93715aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
93725aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
93735aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
93745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
93755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
93765aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
93775aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
93788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
93790b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
93805aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
93815aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
93825aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
93835aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
93845aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
93850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
93865aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
93880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
939026c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93918640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
939226c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
93935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
93940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
93950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
93960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
93970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
93980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
93990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9401d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9402d6bf1617e99df0272b231855a933a74e99b6578fglennrp
94035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
94058a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (image->alpha_trait != BlendPixelTrait && ping_have_non_bw == MagickFalse)
94068d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
94088640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
941135ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
94125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
94130f111984738842d27d04aed2a3f823d82a943506glennrp
94140f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
94150f111984738842d27d04aed2a3f823d82a943506glennrp           {
94160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9417edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"image has 0 colors");
94180f111984738842d27d04aed2a3f823d82a943506glennrp           }
94190f111984738842d27d04aed2a3f823d82a943506glennrp
942035ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
94215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9422d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9424d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9425d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9426d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9427d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
94280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9429d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9430d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9431d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
94320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9433d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9434d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
94375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
94382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94421a56e9c9268976936eeab9fe97eb664b847e444cglennrp        "    Tentative PNG color type: %s (%.20g)",
94431a56e9c9268976936eeab9fe97eb664b847e444cglennrp        PngColorTypeToString(ping_color_type),
94441a56e9c9268976936eeab9fe97eb664b847e444cglennrp        (double) ping_color_type);
94450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9447e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
94480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9450e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
94510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94533c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
94548640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
94558640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94568640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9457e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
946058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
94634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
94647c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
94657c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
94667c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
94672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94687c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
94697c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
94707c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
94712b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
94734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
94754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
94764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
94774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
94784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
94794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9480a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
94814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
94827c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
94837c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
94847c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
94854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
94860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
94884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
94894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9490bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
94930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
94954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
94960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
94984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
94990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
95014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
95020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
95044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
95050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
95074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
95080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
95104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
95110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
95134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
95140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
951616ea139d53d867211d3bb0fa859a83de653f687ecristy                (ScaleQuantumToShort(GetPixelInfoIntensity(
95174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
95180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
95200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
95224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
95230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
95254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
95264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9527fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9528fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9529fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9530fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9531fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
95324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
95332b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
95354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
95367c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
95377c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
95380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
95404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
95414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
95424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
95434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
95444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
95454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
95464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
95474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
95484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
95494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
95525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
95535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
95545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
95555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
95573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
95583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95598640fb5e9b1094f35f8beab436f81661b8a99448glennrp
95603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
95610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95622e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
95640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
956539992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
95678d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
95688d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
95693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
957035ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
95710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
95739c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
95740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95757c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
95763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
95784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
95793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
95804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
95814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
95824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
95834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
95854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
95864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
95874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
95883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
95913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
95920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9593136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9594d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9595f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
95960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
95985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
95990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
96035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
96043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
96075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
96080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
960935ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9610bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
96115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
96123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
96133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
96142b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
96150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
96160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
96183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
96193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
96201a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
96223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
96243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
96253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9626bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
96273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
96283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
96363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
96374bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
96393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
96402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
96429c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
96430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
96459c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
96460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
96489c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
96493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
96525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
96533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
96540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
96560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
965917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
966017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
96613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
96653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
96665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
96670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
966858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
96693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
96709c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
96710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96723b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
96739c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96749c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
96753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
96760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9679bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
96813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
96823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
96833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
96843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
96850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
96873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
968898156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
9689f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
96900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
969139992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
96923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
96930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
9695d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
96963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9697befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
9698befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
9699befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
97005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
9701befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
97020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
970316ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
97045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
97053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
97060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
97080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
970958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
97100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
97110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
9712d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
9713d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
97140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
97153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9716d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
9717d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
97183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
97200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
97210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9722d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
97230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
9724c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
9725c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
9726c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9727c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
9728c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
9729d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
9730d6bf1617e99df0272b231855a933a74e99b6578fglennrp
9731d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
9732d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
9733750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp                       ping_trans_alpha[i]= (png_byte)
973416ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
9735d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
97360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
97370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
97400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
97423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9743c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
97453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
97460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
97483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
97494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
97504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
97514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
97534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
97544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
97554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
97564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
97574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
97585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
97595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
97605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
97615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
97624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
97634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
97644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
97654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
97674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
97684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
97694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
97704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
97733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97744383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
97754383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
97762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
97783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
97793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
97805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
97813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
97823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
97843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
97853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
978635ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
978735ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
978835ef824baa82511126ff0072ae30eee0da9c05a3cristy
978922ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
97903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
979226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
97933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
979416ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
979516ea139d53d867211d3bb0fa859a83de653f687ecristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(
979616ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
979716ea139d53d867211d3bb0fa859a83de653f687ecristy
97983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
97998f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
980016ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
980116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
980216ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
980316ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
98043b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
9805991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
980626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
98073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98083e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
98093e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98103e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
98113e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
98123e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
98139be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
98143e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
98153e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
98163e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
98173e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98183e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
982017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
982126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
982226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
98231273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
982417a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
982517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
982617a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
982717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
982817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
982917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
983017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
9831a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
9832a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
983317a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
983417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
983517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
983617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
98373b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
98380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
98390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
98410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
9842a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
984313d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
9844a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
98450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
98463b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
98473b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
98480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
98490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
98510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
98520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
98530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
98540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
9855a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
985617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
9857d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
98583c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
98593b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
98603b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98613b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
98623c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
98633c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
986417a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
986526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
986617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98691a56e9c9268976936eeab9fe97eb664b847e444cglennrp      "    PNG color type: %s (%d)", PngColorTypeToString(ping_color_type),
98701a56e9c9268976936eeab9fe97eb664b847e444cglennrp      ping_color_type);
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
98723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
98760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
98780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
98810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
98820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
98840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
98880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98894054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
98904054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
989110d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
989210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
989310d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
989410d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
989510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
989610d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
989710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
989810d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0: Use Z_HUFFMAN_ONLY strategy with the
989910d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
990010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
990110d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
990210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
990310d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
990410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
990510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
990610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
990710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
990810d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
990910d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
9910750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
991110d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
991210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
991310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
991410d739ef54404090a55cb8977fc51f85cafa81a5glennrp             a MNG, othewise "none".  Did not work in IM-6.7.0-9
991510d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
991610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
991710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        8:   Z_RLE strategy, all filters
99181868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
991910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
992010d739ef54404090a55cb8977fc51f85cafa81a5glennrp        9:   Z_RLE strategy, no PNG filters
99211868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
992210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
992310d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
992410d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
992516ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
992616ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
992710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
992810d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
992910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
99320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99331868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
99341868258559ddf946fa73ef72dd43507b32623705glennrp    {
99351868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
99361868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
99371868258559ddf946fa73ef72dd43507b32623705glennrp    }
9938750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
99391868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
99403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9944bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
99450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99461868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
99471868258559ddf946fa73ef72dd43507b32623705glennrp    }
99480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99491868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
99501868258559ddf946fa73ef72dd43507b32623705glennrp    {
99511868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
9952a24b245fac14ef0617d691de0942697f2eb31b05glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
9953a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy=Z_RLE+1;
9954a24b245fac14ef0617d691de0942697f2eb31b05glennrp#else
9955a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
9956a24b245fac14ef0617d691de0942697f2eb31b05glennrp#endif
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99591868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
99601868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
99611868258559ddf946fa73ef72dd43507b32623705glennrp
99621868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
99633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99641868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99661868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
99671868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
99680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99691868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
99701868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99711868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
99721868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
99730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99741868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99751868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99774054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
997810d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99791868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
99804054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
99814054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
99821868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99831868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
99841868258559ddf946fa73ef72dd43507b32623705glennrp        else
99851868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99861868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
99871868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99901868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
99911868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
99920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99931868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
99941868258559ddf946fa73ef72dd43507b32623705glennrp    {
99951868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
99961868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
99971868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
99981868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
99991868258559ddf946fa73ef72dd43507b32623705glennrp      else
100001868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
100011868258559ddf946fa73ef72dd43507b32623705glennrp     }
100024054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
100031868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
100041868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
1000510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
100061868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
100071868258559ddf946fa73ef72dd43507b32623705glennrp    {
100081868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
100091868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
100101868258559ddf946fa73ef72dd43507b32623705glennrp      {
100111868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
100121868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
100131868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
100141868258559ddf946fa73ef72dd43507b32623705glennrp      }
100151868258559ddf946fa73ef72dd43507b32623705glennrp#endif
100164054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
100171868258559ddf946fa73ef72dd43507b32623705glennrp    }
100180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100191868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
100201868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
100210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100221868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
100231868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
100241868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
100250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100261868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
100271868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
100281868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
100292b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
100300d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
100310d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
100320d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy     (image->rendering_intent == UndefinedIntent))
100330d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
100340d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
100350d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
100360d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
10037c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
10038c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
10039c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
100403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10041c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
100420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10043c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
10044c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
10045c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
10046c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
10047c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
1004826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
10049c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
10050c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
10051c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
1005216ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
10053e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
10054c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
10055e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
10056e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
10057e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
10058c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
10059c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
1006026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
100610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10062c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10064c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
10065c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
10066cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
10067c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
10068c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
10069c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
10070c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
10071c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
100720b206f5daa453dc1035db5890cabc899736dc2d0glennrp
10073c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
10074c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10075c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
100760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10077c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
10078c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
100790d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
100833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
100845f11bf96e873e4051dcb4682ec3b225ff46c36aeglennrp      (image->rendering_intent != UndefinedIntent))
100853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1008626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
1008726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1008826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
1008926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
1009026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
1009126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
1009226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1009326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
100940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1009526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
10096cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
10097cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
1009826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1010026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
101015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
101023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
101033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101042cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
101052cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
1010626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
1010726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
101083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
101093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
101103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
101113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
101123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
101133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
101143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
101153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
101173b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
101183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
101193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1012026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
101212b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
1012226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1012426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
1012526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
1012626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
1012726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
1012826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
1012926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
1013026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
1013126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
1013226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
1013326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
1013426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
1013526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
1013626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1013726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1013826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1013926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1014026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1014126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1014226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1014326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1014426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1014526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1014626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1014726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1014826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1014926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
101503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10151dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
101525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
101533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
101553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101575d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
101583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10159d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
101603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
101628d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
101633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
101645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
101652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
101665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
101675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
101690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
101718d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
101725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
101733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
101760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
101775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
101795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10180991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
101810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
101823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
101850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
101860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
101870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
101890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
101900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
101913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
101923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
101933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101945d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy                  "  Defined png:bit-depth=%u, Computed depth=%u",
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
101965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
101973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
101980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
102003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
102013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102025d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy                  "  Defined png:color-type=%u, Computed color type=%u",
102033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
102045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
102053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
102063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
102070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
102083bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
102095d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy        "Cannot write image with defined png:bit-depth or png:color-type.");
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102128a46d827a124555f0c48fb2368ec1bba8e079ab6cristy  if (image_matte != MagickFalse && image->alpha_trait != BlendPixelTrait)
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
10215b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait = BlendPixelTrait;
1021616ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageAlpha(image,OpaqueAlpha,exception);
102170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10218b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
10219b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10220b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
102213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102230e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10224e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
10225991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
10226c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
10227991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
10228c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
10229c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10230c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
10231c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
10232e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
10233e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
102343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
102373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
102395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
102405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
102415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
102425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
1024339992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
1024439992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
10245f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
102460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102473b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
1024839992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
102498640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
102500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
10251d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
102520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10253d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10254d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
102550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
102560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
102570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
10258d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
102590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
102600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
102610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10262d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
102630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
102640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
102650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
102660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
102670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
1026839992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
1026939992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
1027039992b4dd9b12ef752d55b8e402c069698851f72glennrp
1027126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1027226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1027326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10274c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1027526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
10276c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging)
10277c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10278c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10279c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10280c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10281c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10282c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10283c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10284c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10285c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10286c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10287c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10288c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10289c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10290c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1029126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10292991d11dd9c33e65872778b81aff1347cd2878154glennrp
1029326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10294dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1029526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1029626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1029726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1029826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1029926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1030026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10301823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
10302823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
10303823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10304823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10305823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10306823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10307823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10308823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10309823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10310823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10311823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10312823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10313823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10314823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10315823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1031626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10317dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10318dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10319dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
103204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10321dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1032226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1032326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1032426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1032526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10326dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1032726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1032826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1032926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1033026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1033126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10332dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10333dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10334dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10335da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10336da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1033716ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10338da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10339da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10340da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10341da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10342da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10343da8f3a7bfddac2680a3069a490db541e7944edafglennrp
103443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10345991d11dd9c33e65872778b81aff1347cd2878154glennrp
1034639992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10347991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
103483b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
103490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
103500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
103520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10353991d11dd9c33e65872778b81aff1347cd2878154glennrp
103540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
103550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
103560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
103570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
103580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10359991d11dd9c33e65872778b81aff1347cd2878154glennrp
103600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
103610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
103620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
103630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
103640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
103650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
103660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103673b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
103680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
103690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10370c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
103710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
103720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
103730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
103740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
103750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
103760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10377991d11dd9c33e65872778b81aff1347cd2878154glennrp
103783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10379cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10380da8f3a7bfddac2680a3069a490db541e7944edafglennrp
103813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10382991d11dd9c33e65872778b81aff1347cd2878154glennrp
103833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10384cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
103853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1038626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
103873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
103894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1039026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1039126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1039226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1039326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1039426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1039526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1039603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1039726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1039826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1039926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1040026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1040126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1040226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
104033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
104043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
104069c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
104073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
104089c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
104093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
104103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
104113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
104133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
104153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10417b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10418b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
104197202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
104203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10421b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
104223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10423b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
104240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10425b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10426b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10427b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
104280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10429b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
104303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10431b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
104320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10433b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10434b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
104353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
104363b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
104373b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
104383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10439b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10440b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
104410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10442b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10443e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
104443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10445cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
10446cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
104470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10448cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
10449edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Allocation of memory for pixels failed");
104500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
104533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10454ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10455ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10456edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation for quantum_info failed");
104573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
104583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
104593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
104608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
104613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
104628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
104638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
104643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
104658d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
104668d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
104673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
104688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1046916ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
104703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
104710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
104733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
104743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
104753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
104763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
104773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10478bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
104793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
104813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10483a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1048416ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
104850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1048616ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
104873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
104880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
104903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1049116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1049216ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
104933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
104943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
104953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
104963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
104973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10498bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10499cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
105003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
105013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
105023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
105030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
105053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1050616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1050716ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
105083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
105090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10511bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10512cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
105133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
105140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105153b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10516b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10517b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
105180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10519cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
105203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
105223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
105233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
105243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
105263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
105283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
105290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
105313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
105333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
1053458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
105355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
105368d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1053816ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
105398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
105400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
105423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
105438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10544bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1054616ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
105472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1054816ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
105493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
105502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
105538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1055416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1055516ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
105562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1055816ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1055916ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
105602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
105628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
105652cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10567b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
105683b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10569b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
105712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1057216ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1057316ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
10574b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
105752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105763b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10577b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
105792cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10580cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
105822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
105848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
105858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
105868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
105878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
105888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
105898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
105908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
105910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1059416ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
105958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
105960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
105998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
106008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
106018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
106028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
106038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10604b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
10605862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
106062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1060716ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
106088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
106092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
106118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
106128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1061316ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1061416ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
106152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1061716ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1061816ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
106198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
106202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
106228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1062316ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10624cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1062516ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
106262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
106288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
106308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
106312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1063316ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1063416ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
106352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1063716ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1063816ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
106392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106403b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10641b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
106432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10644cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
10645b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
106468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
106472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
106498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
106508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
106518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
106528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
106538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
106548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
106558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
106568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
106578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
106592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
106618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
106628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
106632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
106658640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
106668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
106678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
106692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1067016ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
106712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1067216ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
106738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
106742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1067644757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
106774bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
106784bf89731a90c6e03598950223e19e7be7b95d630glennrp
1067916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1068016ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1068144757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
106822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
106848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
106858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
106868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
106882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1068916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10690cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1069116ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
106928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
106932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
106958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1069616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1069716ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
106982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106995eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
107005eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
107015eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107021a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
107035eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
107045eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107055eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
107065eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
107075eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
107088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
10709cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
107108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
107118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
107122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
107138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
107148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
107158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
107168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
107178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
107188640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
107228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10723b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
10724b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10729b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
107300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10732e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
107330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10735e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
107360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107405d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
107450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107495d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
107540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10759a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10761823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
107623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1076326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1076426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1076526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1076626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1076726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1076826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
107692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1077016ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
10771a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10772a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      /* Don't write any "png:" properties; those are just for "identify" */
10773a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(property,"png:",4) != 0 &&
10774a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10775a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
10776a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
10777823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
10778a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
10779a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10780a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
10781a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
10782a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1078326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
10784c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
10785c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
10786a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy
10787a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
10788a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,
10789a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy                 (png_alloc_size_t) sizeof(png_text));
10790a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
10791a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
10792a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
10793c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
10794c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
10795c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
107962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10797c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
10798c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
107992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10800c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
10801c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
108022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10803c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1080426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
10805c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
10806c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
10807c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
10808c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1080926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
108102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10811c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
10812c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
10813c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10814c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
10815c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
10816c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10817c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "    keyword: %s",text[0].key);
10818c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
10819c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
10820c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
10821c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
10822c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1082326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1082426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1082526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
10829cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
108323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
108340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
108360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
108405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
108415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1085103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
108603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
108625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
108655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
10877edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
108780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10885cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1088716ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1088816ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1088916ea139d53d867211d3bb0fa859a83de653f687ecristy
1089016ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1089116ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1089216ea139d53d867211d3bb0fa859a83de653f687ecristy
10893b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
10894b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
10895b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
10896b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1089716ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
10898b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
109020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10903edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
10904edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
10905edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
10906edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
10907edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   /* }  for navigation to beginning of SETJMP-protected block. Revert to
10908edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    *    Throwing an Exception when an error occurs.
10909edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    */
10910edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
10913edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
109173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
109333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1093416ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1093516ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
109403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1094316ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1094416ea139d53d867211d3bb0fa859a83de653f687ecristy%
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
109515d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109535a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
109545a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
109575a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
109585a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
10959e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
10960130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
10961130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
10962130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
10963e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
10964e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
10965e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
109665a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
109675a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
109695a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
109705a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
109715a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
109755a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
109765a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
109775a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
109785a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
109795a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
109823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
109840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
109855a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
109865a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
109903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
10991bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
10992bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
10993bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
109943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
109963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
109993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
110013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
110023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
110043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
110063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
110093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
110103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
110125a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
110135a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
110145a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
110153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
110185a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1101916ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
110293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
11034bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
11035bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
11040bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11042bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110443241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
110450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
11046d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
110470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
110480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
110490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
11050cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
110510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
11052d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
11053d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
110545d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
11055d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
11056d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
11057d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
11058d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
110590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1106316ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
110653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1106621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1106721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1106821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
110693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
110703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
110723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
110733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
110753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1107821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
110795c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
110805c7cf4e469a4dad7e277783749155932252c52dfglennrp
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
110843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11089fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
110903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1109473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
110950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
110980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
11104a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11113b381a2618e8bb9e1e76299676711d0ec1063feabglennrp  value=GetImageOption(image_info,"png:format");
11114b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11115b381a2618e8bb9e1e76299676711d0ec1063feabglennrp  if (value != (char *) NULL)
11116b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
11117b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
11118b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
11119b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
11120b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickFalse;
11121b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickFalse;
11122b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11123b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11124b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11125b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
11126b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickFalse;
11127b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11128b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickFalse;
11129b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11130b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11131b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11132b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
11133b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickFalse;
11134b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickFalse;
11135b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11136b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11137b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    }
111383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111409c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
111419c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
111429c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111479c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
111489c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
111499c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
111500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111518a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      if (image->alpha_trait == BlendPixelTrait)
1115216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
111530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111549c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1115516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
111560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1115716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111629c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
111639c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
111649c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
111650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111668a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      if (image->alpha_trait == BlendPixelTrait)
1116716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
111680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111699c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1117016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
111710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1117216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
111733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
111768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
111783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
111809c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
111810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
111839c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
111840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
111869c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
111870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
111899c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
111900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
111929c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
111930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11194bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1119516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11196bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11197bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11198bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11199bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
112019c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11202bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
112060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
112119c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
112120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1121316ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1121416ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1121516ea139d53d867211d3bb0fa859a83de653f687ecristy
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
112179c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
112180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
112209c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
112210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
112239c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
112240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
112269c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
112270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11228bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1122916ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11230bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11231bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11232bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11233bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
112359c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11236d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
112400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112410dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
112420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
112430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112445d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
112450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
112460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
112470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
112480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
112490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
112510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112525d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
112535d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
112540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
112550dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
112560dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
112570dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11258aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11259aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11260aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
112610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
112630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
112640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
112650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
112670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
112680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
112690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
112710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
112720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11274104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
112750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
112760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1127726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1127826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11279a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1128026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1128126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1128226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1128326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1128426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1128526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1128626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1128726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11288a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1128926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1129026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1129126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1129226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
112938d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
112948d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
112958d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  value=GetImageArtifact(image,"png:preserve-colormap");
112968d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
112978d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     value=GetImageOption(image_info,"png:preserve-colormap");
112988d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
112998d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
113008d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
113011868258559ddf946fa73ef72dd43507b32623705glennrp  /* Thes compression-level, compression-strategy, and compression-filter
113021868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
113031868258559ddf946fa73ef72dd43507b32623705glennrp   */
113041868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-level");
113051868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
113061868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-level");
113071868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
113081868258559ddf946fa73ef72dd43507b32623705glennrp  {
113091868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
113101868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
113111868258559ddf946fa73ef72dd43507b32623705glennrp       */
113121868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
113131868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
113141868258559ddf946fa73ef72dd43507b32623705glennrp
113150ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
113161868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
113171868258559ddf946fa73ef72dd43507b32623705glennrp
113181868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
113191868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
113201868258559ddf946fa73ef72dd43507b32623705glennrp
113211868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
113221868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
113231868258559ddf946fa73ef72dd43507b32623705glennrp
113241868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
113251868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
113261868258559ddf946fa73ef72dd43507b32623705glennrp
113271868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
113281868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
113291868258559ddf946fa73ef72dd43507b32623705glennrp
113301868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
113311868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
113321868258559ddf946fa73ef72dd43507b32623705glennrp
113331868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
113341868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
113351868258559ddf946fa73ef72dd43507b32623705glennrp
113361868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
113371868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
113381868258559ddf946fa73ef72dd43507b32623705glennrp
113391868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
113401868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
113411868258559ddf946fa73ef72dd43507b32623705glennrp
113421868258559ddf946fa73ef72dd43507b32623705glennrp      else
1134316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
113441868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
113451868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
113461868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
113471868258559ddf946fa73ef72dd43507b32623705glennrp    }
113481868258559ddf946fa73ef72dd43507b32623705glennrp
113491868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-strategy");
113501868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
113511868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-strategy");
113521868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
113531868258559ddf946fa73ef72dd43507b32623705glennrp  {
113541868258559ddf946fa73ef72dd43507b32623705glennrp
113551868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
113561868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
113571868258559ddf946fa73ef72dd43507b32623705glennrp
113581868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
113591868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
113601868258559ddf946fa73ef72dd43507b32623705glennrp
113611868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
113621868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
113631868258559ddf946fa73ef72dd43507b32623705glennrp
113641868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1136598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
113661868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1136798c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1136898c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1136998c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
113701868258559ddf946fa73ef72dd43507b32623705glennrp
113711868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1137298c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
113731868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1137498c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1137598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1137698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
113771868258559ddf946fa73ef72dd43507b32623705glennrp
113781868258559ddf946fa73ef72dd43507b32623705glennrp      else
1137916ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
113801868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
113811868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
113821868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
113831868258559ddf946fa73ef72dd43507b32623705glennrp    }
113841868258559ddf946fa73ef72dd43507b32623705glennrp
113851868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-filter");
113861868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
113871868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-filter");
113881868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
113891868258559ddf946fa73ef72dd43507b32623705glennrp  {
113901868258559ddf946fa73ef72dd43507b32623705glennrp
113911868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
113921868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
113931868258559ddf946fa73ef72dd43507b32623705glennrp       *
113941868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
113951868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
113961868258559ddf946fa73ef72dd43507b32623705glennrp       */
113971868258559ddf946fa73ef72dd43507b32623705glennrp
113981868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
113991868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
114001868258559ddf946fa73ef72dd43507b32623705glennrp
11401b19b8125320afb5954bd73b82d00700e8ed9e984cristy      else if (LocaleCompare(value,"1") == 0)
114021868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
114031868258559ddf946fa73ef72dd43507b32623705glennrp
114041868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
114051868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
114061868258559ddf946fa73ef72dd43507b32623705glennrp
114071868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
114081868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
114091868258559ddf946fa73ef72dd43507b32623705glennrp
114101868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
114111868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
114121868258559ddf946fa73ef72dd43507b32623705glennrp
114131868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
114141868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
114151868258559ddf946fa73ef72dd43507b32623705glennrp
114161868258559ddf946fa73ef72dd43507b32623705glennrp      else
1141716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
114181868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
114191868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
114201868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
114211868258559ddf946fa73ef72dd43507b32623705glennrp    }
114221868258559ddf946fa73ef72dd43507b32623705glennrp
1142303812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1142403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
114255c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
114265c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
114275c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11428acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
114295c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
11430acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11431acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11432acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
11433acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
114345c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11435acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
114365c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
1143726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11438acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11439acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
11440acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11441acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1144203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1144303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1144426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1144503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1144603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1144726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1144803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1144926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1145003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
114512cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
114522cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
114532cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
114542cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
114552cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
114562cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
114572cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
114582cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1145903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1146003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1146103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1146203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1146303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1146403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1146503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1146603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1146703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1146803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
11469a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
1147003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1147103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1147203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1147303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1147403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1147503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1147603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1147703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
11478a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1147903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1148003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1148103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1148203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1148303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
114842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1148503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1148603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1148703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1148803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
11489a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
1149003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1149103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1149203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1149303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1149403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1149503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1149603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1149703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
11498a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1149903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1150003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1150103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1150203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
115032cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1150403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1150503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
115062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1150703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1150803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
115092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11510a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11511a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
11512a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1151303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1151403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
115152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1151603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1151703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
115182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1151903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1152003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
115212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1152203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1152303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1152403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1152503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
115262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1152703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1152803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
115292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1153103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
115322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1153403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
115352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11536a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11537a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
115382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1154003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
115412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11542a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11543a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
11544a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1154503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1154603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
115472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1154803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1154903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
115502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1155103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1155203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
115532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1155403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11555ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1155626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1155726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
115585c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
115595c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
115605c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11561acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
115625c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
11563acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11564acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11565acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
11566acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
115675c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11568acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
115695c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
1157026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11571acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11572acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
11573acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11574acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1157503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1157603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1157703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1157803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1157926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1158003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1158126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1158203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
115832cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
115842cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
115852cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
115862cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
115872cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
115882cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
115892cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
115902cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1159103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1159203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1159303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1159403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1159503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1159603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1159703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1159803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1159903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
11600a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickFalse;
1160103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1160203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1160303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1160403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1160503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1160603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1160703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1160803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
11609a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1161003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1161103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1161203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1161303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1161403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
116152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1161603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1161703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1161803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1161903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
11620a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickTrue;
1162103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1162203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1162303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1162403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1162503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1162603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1162703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1162803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
11629a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1163003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1163103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1163203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1163303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
116342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1163503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1163603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
116372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1163803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1163903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
116402cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11641a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11642a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
11643a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1164403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1164503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
116462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1164703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1164803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
116492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1165003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1165103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
116522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1165303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1165403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1165503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1165603812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
116572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1165803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1165903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
116602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1166103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1166203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
116632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1166403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1166503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
116662cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11667a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11668a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
116692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1167003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1167103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
116722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11673a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11674a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
11675a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1167603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1167703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
116782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1167903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1168003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
116812cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1168203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1168303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
116842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1168503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11686ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1168726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1168826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1168903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1169026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1169126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116925d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1169326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1169426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1169526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1169626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1169726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1169826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
11699a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
11700a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11701a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1170226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1170326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1170426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1170526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1170626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1170726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1170826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1170926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1171026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1171126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1171226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1171326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1171426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1171526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1171626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1171726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1171826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1171926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1172026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1172126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1172226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1172326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1172426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1172526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1172626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1172726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
11728a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
11729a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11730a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1173126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1173226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1173326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1173426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1173526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1173626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1173726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1173826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1173926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1174026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1174126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11742b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
117433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1174416ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
117453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
117470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
117493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
117500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
117523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
117533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
117553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
117573ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1175816ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
117593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
117603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
117613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
117623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
117643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
117653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1176703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
117683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
117693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
117713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
117723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
117743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
117753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
117763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
117773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
117793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
117803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
117813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
117823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
117833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1178559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
117863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
117873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
11789fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
117903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
117923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
117933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
117943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
117963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
117978a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     image_info->type==TrueColorMatteType || image->alpha_trait == BlendPixelTrait;
117983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1179959575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1180059575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1180159575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1180259575fa5c228308a41d7f5028390be2083aaaf6dglennrp
11803750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1180459575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1180559575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1180659575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1180759575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
118083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
118103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
118120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
118143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
118153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1181616ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
118170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
118190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
118213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
118220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
118243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
118260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1182716ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
118283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
118293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
118303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
118318a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      jpeg_image->alpha_trait=UndefinedPixelTrait;
118328f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1183316ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1183416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
118353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
118363b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy      (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
118373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
118383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1183959575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1184059575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1184159575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1184259575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1184359575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1184459575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
118453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
118473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
118493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
118507fb2652ba366fc984d1dbb0c66560b91c57dab78cristy    TrueColorType && IsImageGray(image,exception))
118513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
118523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1185359575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1185459575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1185559575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1185659575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1185759575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1185859575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
1185959575fa5c228308a41d7f5028390be2083aaaf6dglennrp        if (transparent)
1186059575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1186159575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1186259575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1186359575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1186459575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1186559575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1186659575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1186759575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1186859575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1186959575fa5c228308a41d7f5028390be2083aaaf6dglennrp
118703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
118713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
118733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
118743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
118753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
118763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1187716ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
118783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1187916ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
118803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
118813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
118833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
118843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
118863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
118873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
118883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11889cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
11890cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
11891cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
118923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1189316ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
118943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1189616ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
118973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
118983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
118993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
119013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1190216ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
119033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1190516ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
119063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
119083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
119093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
119103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
119113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
119133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1191416ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
119153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
119160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
119183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11919e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
11920e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
119213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
119243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
119253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
119263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
119273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
119303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
119313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1193203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
119334e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
119344e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
119353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
119363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
119373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
119383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
119393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
119403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
119413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
119423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
119433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
119443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
119453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
119463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
119473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11948f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
119490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11951f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
119520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
119550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
119580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
119610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
119640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
119670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
119700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
119730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
119763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
11979cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
119803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
119823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
119833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
119843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
119863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
119873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
119883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
119893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
119903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
119923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
119933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
119943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
119953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11996bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
119973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
119983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
120003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
120013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
120023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
12003bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
120043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1200503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
120063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
120073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
120083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
120093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
120103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
120113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
120123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
120133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
120143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
120153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
120163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
120173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
120183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
120203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
120223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
120233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
120243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
120253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1202603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
120270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
12029e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12030cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12031e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
120320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12034e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12035cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12036e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
120370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
120393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
120403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
120423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
120443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
120453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
120463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
120473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
120483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
120493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1205003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1205135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
120523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
120533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
120543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
120550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
120573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
120583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
120593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
120603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
120613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
120633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
120643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
120653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
120663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1206703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
120683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1206935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1207035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
120713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1207235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1207335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
120743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1207535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1207635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
120773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1207835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1207935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
120803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
120813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
120823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
120833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1208516ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
120863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
120883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
120893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
120903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
120913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1209203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
120933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
120943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1209535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1209616ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
120970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1209835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1209916ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
121000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
121023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
121030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
121053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
121063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
121073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1210835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1210916ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
121100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1211135ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1211216ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
121130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
121153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
121160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
121183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1211916ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1212016ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
121213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
121223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
121233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
121243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
121253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
121263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
121273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
121293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
121313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
121323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
121333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
121343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1213503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12136bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12137bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
121383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
121393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
121403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
121413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
121423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
121433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
121453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1214603812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
121473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
121483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
121493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
121513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
121523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
121533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
121563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
121583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12159bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
121603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
121613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12162bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
121633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
121643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
121663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
121673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12168e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12169f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
121703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
121723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
121733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
121753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
121763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
121773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
121780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
121803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
121813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12182bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1218303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
121843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
121853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
121863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
121873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
121880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
121903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
121923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12193e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12194e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
121953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
121963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
121973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
121983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
121993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
122003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
122023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12204e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12205bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
122063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1220703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
122083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
122093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
122103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
122113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
122123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
122133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
122163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
122183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
122213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
122223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
122233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
122283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1222916ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
122303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
122313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
122353b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
122363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
122373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1223916ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
122403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12243e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12244e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
122453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
122473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
122480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122493080b916bc1e53af65fa199eba114729f5c76c41cristy  *jpeg_image_info->filename='\0';
1225059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1225159575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
122523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
122533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
122580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1225916ea139d53d867211d3bb0fa859a83de653f687ecristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,exception);
122600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12264e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12265e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
122663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12268e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
122693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
122700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12272bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
122733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1227403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
122753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
122763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
122783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
122803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
122813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
122823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12285cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
122863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
122883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
122893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1229003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
122913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
122923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
122933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
122970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
122993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
123003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
123033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
123143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
123163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
123183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1231916ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1232016ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
123253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
123273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1232816ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1232916ea139d53d867211d3bb0fa859a83de653f687ecristy%
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1233216ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1233316ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
123343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
123353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1233621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1233703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
123393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
123413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
123423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
123453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
123473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
123483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
123493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
123503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12351fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1235216ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
123533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
123553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
123583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1236073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
123623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
123633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
123653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
123673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
123683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
123693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1237216ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
123743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
123763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
123803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1238316ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1238416ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
123853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
123863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
123873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
123883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1239321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1239603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1239703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1239803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
123993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
124013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
124043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
124053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
124063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
124083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
124093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
124103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
124113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
124123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
124133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
124143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
124153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12416bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
124173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
124203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
124213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12426bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12429bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
124303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
124313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
124323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12433d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
124343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
124353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
124363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
124373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
124383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
124453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
124463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12447fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1244816ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
124493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
124503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
124513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
124543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
124553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1245673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
124573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
124583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
124593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
124613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
124623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
124633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
124643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
124653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
124693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
124703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
124713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
124723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
124733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
124743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
124753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
124763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
124773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
124793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
124803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
124813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
124833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
124843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
124853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
124873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
124883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
124903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
124923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
124933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
124943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
124970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12499e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
125000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
125033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
125053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12508e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
125090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12511e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
125120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125138a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        if (p->alpha_trait)
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
125160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
125200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
125223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
125240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
125263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
125280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
125303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12531e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
125320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
125360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
125383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
125393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
125403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
125433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
125443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
125453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
125463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
125473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
125483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
125493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
125503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
125533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
125543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
125563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
125583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
125603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
125633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
125653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
125663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
125683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
125693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
125713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
125733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
125753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
125763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
125773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
125793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
125833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
125843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
125873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
125883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
125893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
125903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
125943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
125953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
125963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
125990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
126030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
126053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
126060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126078a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        if (next_image->alpha_trait)
126083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
126090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
126118a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (next_image->alpha_trait || next_image->page.x || next_image->page.y ||
126123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
126133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
126143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
126150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
126180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
126200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
126223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
126233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
126240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
126263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
126273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
126283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
126293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
126308a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        if (image->alpha_trait == BlendPixelTrait)
126313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
126320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
126343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
126357fb2652ba366fc984d1dbb0c66560b91c57dab78cristy            if (IsImageGray(image,exception) == MagickFalse)
126363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
126373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
126383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
126393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
126403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
126423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
126433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
126443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
126453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
126463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
126473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
126483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
126493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
126503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
126513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
126520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
126543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
126550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
126573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
126583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
126590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1266116ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1266216ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
126640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
126683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
126703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
126713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
126723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
126753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
126773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
126783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
126793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
126803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
126833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
126883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
126893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
126903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
126933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
126963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
126973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
126983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
126993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
127013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
127020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
127063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
127073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
127103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
127133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
127143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
127153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
127160261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
12717d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
12718d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1271916ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1272016ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
12721d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
12722d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
12723d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
12729cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
12730cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
127323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
127330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
127360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
127383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
127390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
127423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
127433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
127453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
127523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
127533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
127543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
127563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
127573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
127583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1276003812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
127614e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
127624e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
127730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
127753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
127763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
127793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
127820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
127893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
127933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
127940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
127973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
128013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
128030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
128063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
128113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
128123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
128143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
128193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
12821bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1282203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
128253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
128263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
128293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
128323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
128333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1283603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
128373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
128383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
128410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
128440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
128470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12851e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
12852e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
128530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12856e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
128570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12860e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
128633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
128673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
128683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
128743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
128753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1287603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
128770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
12879e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
12880cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
12881e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
128820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
12884e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
12885cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
12886cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
128870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
128893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
128903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
128913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
128963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
128973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
128983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
129003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
129013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1290203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1290335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
129043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
129053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
129063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
129073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
129083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
129093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
129113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
129123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
129163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1291803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1292035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1292135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1292335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1292435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1292635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1292735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
129283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1292935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1293035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
129313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
129323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
129343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1293616ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
129373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
129393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
129403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
129423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1294303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
129440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1294735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1294816ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
129490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1295035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1295116ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
129520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
129550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
129573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
129583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1296035ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1296116ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
129620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1296335ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1296416ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
129650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
129673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
129680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1297116ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1297216ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
129743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
129763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
129773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
129783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
129793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
129803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
129823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
129838a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     if (write_mng && (image->alpha_trait || image->page.x > 0 ||
129843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
129853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
129863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
129873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
129883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
129893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
129903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1299103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
129923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
129963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
129973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
129983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
129993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
130013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1300403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
130063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
130073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
130083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
130093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
130113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
130123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
130133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
13015bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
130163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
130173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
130193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
130203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
130213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1302403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
130250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13026bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1302816ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1302916ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1303016ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1303116ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1303216ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1303316ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
130350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
130373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
130383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
130393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
130403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
130423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
130433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
130443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
130473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
130493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
130503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
130513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
130563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
130573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
130583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
130603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
130613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
130633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
130653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
130663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
130673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
130703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
130723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
13073bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
130743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
130753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
130773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
130783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1307903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
130800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13081bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
130823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
130833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
130843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
130853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
130863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
130870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
130893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
130903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
130913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
130923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
130933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
130953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
130963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
130973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
130993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13100bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
131013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
131023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
131033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
131073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
131083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
131103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
131113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
131123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
131133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
131143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
131153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
131163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
131173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
131183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
131193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1312003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
131213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
131223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
131233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
131243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
131273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
131293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
131303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
131313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
131343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
131363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
131373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
131393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
131403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
131413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
131423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
131433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
131463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
131473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1314903812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
131503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
131513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
131533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
131543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
131553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
131563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
131573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
131583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
131593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
131603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1316103812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
131623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
131633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
131643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
131653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
131663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
131673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
131683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
131693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
131703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
131713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
131723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
131734e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
131743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
131753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
131763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
131773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
131793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
131803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
131813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
131823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
131833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
131853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
131863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
131873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
131883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
131893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1319016ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
131913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
131923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
131933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
131943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
131953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
131963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
131973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
131983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
131992f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13200b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
132018d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
132022f2e514554975d510c88df54de98c6cdc1080f1cglennrp
132032f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
132042f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
132052f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13206a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
132072f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
132082f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
132092f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
132102f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
132112f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
132122f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
132132f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
132142f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13215a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
132162f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
132172f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
132182f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
132192f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1322016ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
132213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
132223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
132243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
132253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
132263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
132273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
132283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
132293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
132303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
132313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
132323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
132333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
132343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
132350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
132373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
132380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
132400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
132423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
132433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
132443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
132453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
132463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
132473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
132483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
132493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1325003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
132513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
132523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
132533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
132543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
132553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
132563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
132573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
132583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
132590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
132613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
132620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
132643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13265d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1326639992b4dd9b12ef752d55b8e402c069698851f72glennrp
132673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
132683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
132693bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
132703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
132713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
132720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
132743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
132753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1327639992b4dd9b12ef752d55b8e402c069698851f72glennrp
132773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
132783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
132793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
132803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13281d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
132823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13283