png.c revision a3a5f956194e91458e2789966ad15308e8f3df47
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%                                                                             %
2145ef08fd6a09813e4a8f5ddadf85ba9e0ec2cdc7cristy%  Copyright 1999-2013 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) \
170360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelRed(image, \
171360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelRed(image,(pixel))) < 0x10 ? \
172c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
1738e58efdecda887b08ef730d68290a61081ef2566glennrp
17454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelGreen(pixel) \
175360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelGreen(image, \
176360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelGreen(image,(pixel))) < 0x10 ? \
177c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
1788e58efdecda887b08ef730d68290a61081ef2566glennrp
17954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelBlue(pixel) \
180360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelBlue(image, \
181360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelBlue(image,(pixel))) < 0x10 ? \
182c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
1838e58efdecda887b08ef730d68290a61081ef2566glennrp
18416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelAlpha(pixel) \
185360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelAlpha(image, \
186360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) < 0x10 ? \
187c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
1888e58efdecda887b08ef730d68290a61081ef2566glennrp
18954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelRGB(pixel) \
190bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
191ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR01PixelRed((pixel)); \
19254cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelGreen((pixel)); \
19354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelBlue((pixel)); \
194bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1958e58efdecda887b08ef730d68290a61081ef2566glennrp
19616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelRGBA(pixel) \
197bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
19854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelRGB((pixel)); \
19916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PixelAlpha((pixel)); \
200bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2018e58efdecda887b08ef730d68290a61081ef2566glennrp
2028e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR02: Replicate top 2 bits */
2038e58efdecda887b08ef730d68290a61081ef2566glennrp
20405001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR02PacketRed(pixelpacket) \
2058e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2068e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xc0; \
2078e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2088e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2098e58efdecda887b08ef730d68290a61081ef2566glennrp   }
21091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketGreen(pixelpacket) \
2118e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2128e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xc0; \
2138e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2148e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2158e58efdecda887b08ef730d68290a61081ef2566glennrp   }
21691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketBlue(pixelpacket) \
2178e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2188e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xc0; \
2198e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
2208e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2218e58efdecda887b08ef730d68290a61081ef2566glennrp   }
22216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PacketAlpha(pixelpacket) \
2238e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
22416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xc0; \
22516ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum( \
2268e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2278e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2288e58efdecda887b08ef730d68290a61081ef2566glennrp
22991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGB(pixelpacket) \
230bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
23105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR02PacketRed((pixelpacket)); \
23291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketGreen((pixelpacket)); \
23391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue((pixelpacket)); \
234bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2358e58efdecda887b08ef730d68290a61081ef2566glennrp
23691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGBO(pixelpacket) \
237bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
23891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketRGB((pixelpacket)); \
23916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PacketAlpha((pixelpacket)); \
240bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2418e58efdecda887b08ef730d68290a61081ef2566glennrp
242ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR02PixelRed(pixel) \
2438e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
24416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
2458e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
24616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
24716ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
24816ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2498e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelGreen(pixel) \
2518e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
25216ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
2538e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
25416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
25516ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
25616ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2578e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25854cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelBlue(pixel) \
2598e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2608e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
26116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xc0; \
26216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
26316ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
26416ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2658e58efdecda887b08ef730d68290a61081ef2566glennrp   }
26616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelAlpha(pixel) \
2678e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2688e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
26916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xc0; \
27016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image, ScaleCharToQuantum( \
27116ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
27216ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel) ); \
2738e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2748e58efdecda887b08ef730d68290a61081ef2566glennrp
27554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelRGB(pixel) \
276bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
277ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR02PixelRed((pixel)); \
27854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelGreen((pixel)); \
27954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelBlue((pixel)); \
280bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2818e58efdecda887b08ef730d68290a61081ef2566glennrp
28216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelRGBA(pixel) \
283bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
28454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelRGB((pixel)); \
28516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PixelAlpha((pixel)); \
286bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2878e58efdecda887b08ef730d68290a61081ef2566glennrp
2888e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR03: Replicate top 3 bits (only used with opaque pixels during
2898e58efdecda887b08ef730d68290a61081ef2566glennrp   PNG8 quantization) */
2908e58efdecda887b08ef730d68290a61081ef2566glennrp
29105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR03PacketRed(pixelpacket) \
2928e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2938e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xe0; \
2948e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2958e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
2968e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29791d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketGreen(pixelpacket) \
2988e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2998e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xe0; \
3008e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
3018e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3028e58efdecda887b08ef730d68290a61081ef2566glennrp   }
30391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketBlue(pixelpacket) \
3048e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3058e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xe0; \
3068e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
3078e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3088e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3098e58efdecda887b08ef730d68290a61081ef2566glennrp
31091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketRGB(pixelpacket) \
311bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
31205001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR03PacketRed((pixelpacket)); \
31391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketGreen((pixelpacket)); \
31491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketBlue((pixelpacket)); \
315bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3168e58efdecda887b08ef730d68290a61081ef2566glennrp
317ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR03PixelRed(pixel) \
3188e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
31916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3208e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
32116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
32216ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3238e58efdecda887b08ef730d68290a61081ef2566glennrp   }
32416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Green(pixel) \
3258e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
32616ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3278e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
32816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
32916ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3308e58efdecda887b08ef730d68290a61081ef2566glennrp   }
33116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Blue(pixel) \
3328e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
33316ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelBlue(image,(pixel))) \
3348e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
33516ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
33616ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3378e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3388e58efdecda887b08ef730d68290a61081ef2566glennrp
33916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03RGB(pixel) \
340bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
341ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR03PixelRed((pixel)); \
34216ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Green((pixel)); \
34316ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Blue((pixel)); \
344bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3458e58efdecda887b08ef730d68290a61081ef2566glennrp
3468e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR04: Replicate top 4 bits */
3478e58efdecda887b08ef730d68290a61081ef2566glennrp
34805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR04PacketRed(pixelpacket) \
3498e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3508e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xf0; \
3518e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3528e58efdecda887b08ef730d68290a61081ef2566glennrp   }
35391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketGreen(pixelpacket) \
3548e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3558e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xf0; \
3568e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3578e58efdecda887b08ef730d68290a61081ef2566glennrp   }
35891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketBlue(pixelpacket) \
3598e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3608e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xf0; \
3618e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3628e58efdecda887b08ef730d68290a61081ef2566glennrp   }
36316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PacketAlpha(pixelpacket) \
3648e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
36516ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xf0; \
36616ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3678e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3688e58efdecda887b08ef730d68290a61081ef2566glennrp
36991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGB(pixelpacket) \
370bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
37105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR04PacketRed((pixelpacket)); \
37291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketGreen((pixelpacket)); \
37391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketBlue((pixelpacket)); \
374bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3758e58efdecda887b08ef730d68290a61081ef2566glennrp
37691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGBO(pixelpacket) \
377bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
37891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB((pixelpacket)); \
37916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PacketAlpha((pixelpacket)); \
380bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3818e58efdecda887b08ef730d68290a61081ef2566glennrp
382ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR04PixelRed(pixel) \
3838e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
38416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3858e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
38616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
38716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3888e58efdecda887b08ef730d68290a61081ef2566glennrp   }
38954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelGreen(pixel) \
3908e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
39116ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3928e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
39316ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
39416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3958e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelBlue(pixel) \
3978e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3988e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
39916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xf0; \
40016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
40116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4028e58efdecda887b08ef730d68290a61081ef2566glennrp   }
40316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelAlpha(pixel) \
4048e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4058e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
40616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xf0; \
40716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
40816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4098e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4108e58efdecda887b08ef730d68290a61081ef2566glennrp
41154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelRGB(pixel) \
412bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
413ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR04PixelRed((pixel)); \
41454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelGreen((pixel)); \
41554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelBlue((pixel)); \
416bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4178e58efdecda887b08ef730d68290a61081ef2566glennrp
41816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelRGBA(pixel) \
419bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
42054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelRGB((pixel)); \
42116ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PixelAlpha((pixel)); \
422bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4238e58efdecda887b08ef730d68290a61081ef2566glennrp
4248e58efdecda887b08ef730d68290a61081ef2566glennrp
4251145899ed6265fc5762cdf8a7be237d12622e740glennrp#if MAGICKCORE_QUANTUM_DEPTH > 8
4268e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR08: Replicate top 8 bits */
4278e58efdecda887b08ef730d68290a61081ef2566glennrp
42805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR08PacketRed(pixelpacket) \
4298e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4308e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red); \
4318e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits)); \
4328e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketGreen(pixelpacket) \
4348e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4358e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green); \
4368e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits)); \
4378e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketBlue(pixelpacket) \
4398e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4408e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue); \
4418e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits)); \
4428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
44316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PacketAlpha(pixelpacket) \
4448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
44516ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha); \
44616ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits)); \
4478e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4488e58efdecda887b08ef730d68290a61081ef2566glennrp
44991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketRGB(pixelpacket) \
450bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
45105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR08PacketRed((pixelpacket)); \
45291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketGreen((pixelpacket)); \
45391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketBlue((pixelpacket)); \
454bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4558e58efdecda887b08ef730d68290a61081ef2566glennrp
45691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketRGBO(pixelpacket) \
457bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
45891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketRGB((pixelpacket)); \
45916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR08PacketAlpha((pixelpacket)); \
460bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4618e58efdecda887b08ef730d68290a61081ef2566glennrp
462ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR08PixelRed(pixel) \
4638e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4648e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
46516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelRed(image,(pixel))); \
46616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
46716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4688e58efdecda887b08ef730d68290a61081ef2566glennrp   }
46954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelGreen(pixel) \
4708e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4718e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
47216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelGreen(image,(pixel))); \
47316ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
47416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4758e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelBlue(pixel) \
4778e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4788e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
47916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))); \
48016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
48116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4828e58efdecda887b08ef730d68290a61081ef2566glennrp   }
48316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PixelAlpha(pixel) \
4848e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4858e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
48616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))); \
48716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
48816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4898e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4908e58efdecda887b08ef730d68290a61081ef2566glennrp
49154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelRGB(pixel) \
492bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
493ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR08PixelRed((pixel)); \
49454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelGreen((pixel)); \
49554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelBlue((pixel)); \
496bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4978e58efdecda887b08ef730d68290a61081ef2566glennrp
49816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PixelRGBA(pixel) \
499bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
50054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelRGB((pixel)); \
50116ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR08PixelAlpha((pixel)); \
502bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5031145899ed6265fc5762cdf8a7be237d12622e740glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 8 */
5048e58efdecda887b08ef730d68290a61081ef2566glennrp
5058e58efdecda887b08ef730d68290a61081ef2566glennrp
50615f0766cc205b6cfc220afec824c43e7c8ef8888glennrp#if MAGICKCORE_QUANTUM_DEPTH > 16
5078e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR16: Replicate top 16 bits */
5088e58efdecda887b08ef730d68290a61081ef2566glennrp
50905001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR16PacketRed(pixelpacket) \
5108e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5118e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).red); \
5128e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleShortToQuantum((lbr_bits)); \
5138e58efdecda887b08ef730d68290a61081ef2566glennrp   }
51491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketGreen(pixelpacket) \
5158e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5168e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).green); \
5178e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleShortToQuantum((lbr_bits)); \
5188e58efdecda887b08ef730d68290a61081ef2566glennrp   }
51991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketBlue(pixelpacket) \
5208e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5218e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).blue); \
5228e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleShortToQuantum((lbr_bits)); \
5238e58efdecda887b08ef730d68290a61081ef2566glennrp   }
52416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PacketAlpha(pixelpacket) \
5258e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
52616ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).alpha); \
52716ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleShortToQuantum((lbr_bits)); \
5288e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5298e58efdecda887b08ef730d68290a61081ef2566glennrp
53091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketRGB(pixelpacket) \
531bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
53205001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR16PacketRed((pixelpacket)); \
53391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketGreen((pixelpacket)); \
53491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketBlue((pixelpacket)); \
535bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5368e58efdecda887b08ef730d68290a61081ef2566glennrp
53791d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketRGBO(pixelpacket) \
538bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
53991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketRGB((pixelpacket)); \
54016ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR16PacketAlpha((pixelpacket)); \
541bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5428e58efdecda887b08ef730d68290a61081ef2566glennrp
543ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR16PixelRed(pixel) \
5448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5458e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
54616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelRed(image,(pixel))); \
54716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
54816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5498e58efdecda887b08ef730d68290a61081ef2566glennrp   }
55054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelGreen(pixel) \
5518e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5528e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
55316ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelGreen(image,(pixel))); \
55416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
55516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5568e58efdecda887b08ef730d68290a61081ef2566glennrp   }
55754cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelBlue(pixel) \
5588e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5598e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
56016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelBlue(image,(pixel))); \
56116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
56216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
56416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PixelAlpha(pixel) \
5658e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5668e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
56716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelAlpha(image,(pixel))); \
56816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
56916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5708e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5718e58efdecda887b08ef730d68290a61081ef2566glennrp
57254cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelRGB(pixel) \
573bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
574ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR16PixelRed((pixel)); \
57554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelGreen((pixel)); \
57654cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelBlue((pixel)); \
577bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5788e58efdecda887b08ef730d68290a61081ef2566glennrp
57916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PixelRGBA(pixel) \
580bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
58154cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelRGB((pixel)); \
58216ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR16PixelAlpha((pixel)); \
583bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
58415f0766cc205b6cfc220afec824c43e7c8ef8888glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 16 */
5858e58efdecda887b08ef730d68290a61081ef2566glennrp
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
595edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
597cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  *ping_semaphore = (SemaphoreInfo *) NULL;
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
634bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
64985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
65085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
65185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
65285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
65385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
65485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
65585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
65685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
65785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
65885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
65985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
66085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
66185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
66285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
66385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
66485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
66585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
66685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
66785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
66885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
66985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
67085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
67185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
67285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
67385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
67485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
67585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
67685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
67785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
67885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
67985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
68085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
68185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
68485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
68585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
68685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
68785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
68885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
68985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
69485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
69585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
69685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
69785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
69885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
69985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
70085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
70185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7158182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
724bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
802bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84835ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
858b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
859b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
860b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
8781868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_level,
8791868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_strategy,
8801868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_filter,
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
883fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png32,
884fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png48,
885fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png64;
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
888bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91716ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
92126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
92226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
92326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
924a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
92526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
92626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
92726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
92826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
92926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
93026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
93126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
93226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
933a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
93426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
93526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
9368d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_exclude_zTXt,
9378d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap;
93826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
94616ea139d53d867211d3bb0fa859a83de653f687ecristy  WritePNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
94916ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteMNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
95316ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteJNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
9570c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
958fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
9600c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
96116ea139d53d867211d3bb0fa859a83de653f687ecristyLosslessReduceDepthOK(Image *image,ExceptionInfo *exception)
9620c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
9639d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp    /* Reduce bit depth if it can be reduced losslessly from 16+ to 8.
96467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
96567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * This is true if the high byte and the next highest byte of
96667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * each sample of the image, the colormap, and the background color
9673faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are equal to each other.  We check this by seeing if the samples
9683faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are unchanged when we scale them down to 8 and back up to Quantum.
96967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
97067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * We don't use the method GetImageDepth() because it doesn't check
9713faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * background and doesn't handle PseudoClass specially.
9729d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp     */
97305a549971fd661147ade177e2bc10f6cfcfc32b4glennrp
9743faa9a3fb01696daaf976d595f492cb530bffb21glennrp#define QuantumToCharToQuantumEqQuantum(quantum) \
9753faa9a3fb01696daaf976d595f492cb530bffb21glennrp  ((ScaleCharToQuantum((unsigned char) ScaleQuantumToChar(quantum))) == quantum)
9763faa9a3fb01696daaf976d595f492cb530bffb21glennrp
97767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    MagickBooleanType
97867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      ok_to_reduce=MagickFalse;
97967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
98003e11f6e8d7f01a32b53d7e8e6a3bfd5ef1c5c9dglennrp    if (image->depth >= 16)
9810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
9820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
98316ea139d53d867211d3bb0fa859a83de653f687ecristy        const Quantum
9840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
9850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
9873faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.red) &&
9883faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.green) &&
9893faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.blue) ?
9903faa9a3fb01696daaf976d595f492cb530bffb21glennrp           MagickTrue : MagickFalse;
9910c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
9930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
9940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
9950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
9970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
9983faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=(
9993faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
10003faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].red) &&
10013faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
10023faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].green) &&
10033faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
10043faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].blue)) ?
10053faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
10063faa9a3fb01696daaf976d595f492cb530bffb21glennrp
10070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
10083faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   break;
10090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
10100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
10110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
10130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
10140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
10150c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
10160c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
10170c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10180c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
10190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
10200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
10220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
102316ea139d53d867211d3bb0fa859a83de653f687ecristy              p=GetVirtualPixels(image,0,y,image->columns,1,exception);
10240c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
102516ea139d53d867211d3bb0fa859a83de653f687ecristy              if (p == (const Quantum *) NULL)
10260c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
10270c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
10280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
10300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
10320c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
10333faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=
103416ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelRed(image,p)) &&
103516ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelGreen(image,p)) &&
103616ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelBlue(image,p)) ?
10373faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
10380c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
10400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10410c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
104216ea139d53d867211d3bb0fa859a83de653f687ecristy                p+=GetPixelChannels(image);
10430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
10448640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
10450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
10460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
10470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
10480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
10500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
10510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    OK to reduce PNG bit depth to 8 without loss of info");
10530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
1054a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
1055a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
1056a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1057fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    Not OK to reduce PNG bit depth to 8 without loss of info");
1058a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
10590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
10600c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10610c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
10620c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
10630c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
10640c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10651a56e9c9268976936eeab9fe97eb664b847e444cglennrpstatic const char* PngColorTypeToString(const unsigned int color_type)
10661a56e9c9268976936eeab9fe97eb664b847e444cglennrp{
10671a56e9c9268976936eeab9fe97eb664b847e444cglennrp  const char
10681a56e9c9268976936eeab9fe97eb664b847e444cglennrp    *result = "Unknown";
10691a56e9c9268976936eeab9fe97eb664b847e444cglennrp
10701a56e9c9268976936eeab9fe97eb664b847e444cglennrp  switch (color_type)
10711a56e9c9268976936eeab9fe97eb664b847e444cglennrp    {
10721a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY:
10731a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray";
10741a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10751a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY_ALPHA:
10761a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray+Alpha";
10771a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10781a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_PALETTE:
10791a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Palette";
10801a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10811a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB:
10821a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB";
10831a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10841a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB_ALPHA:
10851a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB+Alpha";
10861a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10871a56e9c9268976936eeab9fe97eb664b847e444cglennrp    }
10881a56e9c9268976936eeab9fe97eb664b847e444cglennrp
10891a56e9c9268976936eeab9fe97eb664b847e444cglennrp  return result;
10901a56e9c9268976936eeab9fe97eb664b847e444cglennrp}
10911a56e9c9268976936eeab9fe97eb664b847e444cglennrp
1092e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
1093cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
10940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1095e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
1096e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1097e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
1098e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
10990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1100e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
1101e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
11020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1103e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
1104e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
11050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1106e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
1107e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
11080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1109e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1110e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
1111e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
1112e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1113e610a071534e448c46460a5aa39ede33bf56b329glennrp
1114e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
1115cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_from_PNG_RenderingIntent(const int ping_intent)
11160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1117cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  switch (ping_intent)
1118e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1119e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
1120e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
11210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1122e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
1123e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
11240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1125e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
1126e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
11270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1128e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
1129e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
11300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1131e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1132e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
1133e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
1134e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1135e610a071534e448c46460a5aa39ede33bf56b329glennrp
11369d8c12213abd15fee2d84da62d3e5145d9db06cdcristystatic const char *
113798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrpMagick_RenderingIntentString_from_PNG_RenderingIntent(const int ping_intent)
113898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp{
113998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  switch (ping_intent)
114098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
114198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 0:
114298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Perceptual Intent";
114398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
114498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 1:
114598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Relative Intent";
114698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
114798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 2:
114898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Saturation Intent";
114998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
115098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 3:
115198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Absolute Intent";
115298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
115398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    default:
115498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Undefined Intent";
115598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
115698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp}
115798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
1158bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
11620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
1166d9ecd04e9c567113b4b605cf76681cbb37c093cdcristystatic const char *
11675dff435eceea4f80207a906b11e65aed48fe3f27glennrpMagick_ColorType_from_PNG_ColorType(const int ping_colortype)
11685dff435eceea4f80207a906b11e65aed48fe3f27glennrp{
11695dff435eceea4f80207a906b11e65aed48fe3f27glennrp  switch (ping_colortype)
11705dff435eceea4f80207a906b11e65aed48fe3f27glennrp  {
11715dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 0:
11725dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Grayscale";
11735dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11745dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 2:
11755dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Truecolor";
11765dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11775dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 3:
11785dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Indexed";
11795dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11805dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 4:
11815dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "GrayAlpha";
11825dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11835dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 6:
11845dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "RGBA";
11855dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11865dff435eceea4f80207a906b11e65aed48fe3f27glennrp    default:
11875dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "UndefinedColorType";
11885dff435eceea4f80207a906b11e65aed48fe3f27glennrp    }
11895dff435eceea4f80207a906b11e65aed48fe3f27glennrp}
11905dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11915dff435eceea4f80207a906b11e65aed48fe3f27glennrp
1192bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
11960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1199d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
13050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
13080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1317d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1318bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1340a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1348a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
136103812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
136203812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1366e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
1367e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1369d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1375d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
1457f54e295d6fa414fa04aa4f43767c20eda8ae555eglennrp%    the original PNG from files that have been converted to Xcode-PNG,
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14883b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy          (void) FormatLocaleString(msg,MaxTextExtent,
1489e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1490e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1518bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
15340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
15370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
15950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1609bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1621bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
16280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
16430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
16480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1661bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1663bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
166721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
166821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
167021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1672bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
16770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
16810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
16950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
16980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
17010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
17040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1717bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1718bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1719bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1737bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17398182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
17408182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
17410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17518182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
175616ea139d53d867211d3bb0fa859a83de653f687ecristytypedef struct _PNGErrorInfo
175716ea139d53d867211d3bb0fa859a83de653f687ecristy{
175816ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
175916ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
176016ea139d53d867211d3bb0fa859a83de653f687ecristy
176116ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
176216ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
176316ea139d53d867211d3bb0fa859a83de653f687ecristy} PNGErrorInfo;
176416ea139d53d867211d3bb0fa859a83de653f687ecristy
1765cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
176716ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
176816ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
176916ea139d53d867211d3bb0fa859a83de653f687ecristy
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
177316ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
177416ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
17750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
177616ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
177716ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
177816ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
1779c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy
178016ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
178116ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
178216ea139d53d867211d3bb0fa859a83de653f687ecristy
178316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,message,
178416ea139d53d867211d3bb0fa859a83de653f687ecristy    "`%s'",image->filename);
17850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1786e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
17878371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
17888371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
17898371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1791faa852bad40107edae19405e76a299057668d795glennrp#else
1792faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1793faa852bad40107edae19405e76a299057668d795glennrp#endif
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1796cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
179816ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
179916ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
180016ea139d53d867211d3bb0fa859a83de653f687ecristy
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
180416ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
180516ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
180616ea139d53d867211d3bb0fa859a83de653f687ecristy
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
18090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
181016ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
181116ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
181216ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
181316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
181416ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
18150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
181616ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1821a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
1822a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_alloc_size_t size)
1823a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
1824a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_size_t size)
1825a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1827df0d90e1d3bbfa3956818ac7bf43aa0d008020dccristy  (void) png_ptr;
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1834cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
18363bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) png_ptr;
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1847edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrpMagick_png_read_raw_profile(png_struct *ping,Image *image,
1848edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   const ImageInfo *image_info, png_textp text,int ii,ExceptionInfo *exception)
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1850bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18660c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1883f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
18840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
188597f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
188697f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
188797f90e23c85b9c58387880125c29d8c99126f83aglennrp
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1894edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping,"invalid profile length");
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18988723e4bcd840478cecfd29891e792edb499cd0e9cristy  profile=BlobToStringInfo((const void *) NULL,length);
18990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1902edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping, "unable to copy profile");
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
19090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1910bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1916edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp          png_warning(ping, "ran out of profile data");
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
19250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
193216ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProfile(image,&text[ii].key[17],profile,exception);
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
19340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
19370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19562ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp  LogMagickEvent(CoderEvent,GetMagickModule(),
19572ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp     " read_vpag_chunk: found %c%c%c%c chunk",
19582ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp       chunk->name[0],chunk->name[1],chunk->name[2],chunk->name[3]);
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1974bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
19760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2025cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tIME chunk into the date:modify property */
2026cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tEXt/Creation Time chunk into the date:create property */
2027cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2031d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  char
2032ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    im_vers[32],
2033ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    libpng_runv[32],
2034ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    libpng_vers[32],
2035ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    zlib_runv[32],
2036ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    zlib_vers[32];
2037d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
203998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    intent, /* "PNG Rendering intent", which is ICC intent + 1 */
2040cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
20424eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
2044913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp    number_colors,
2045faa852bad40107edae19405e76a299057668d795glennrp    pass,
2046faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
2047faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
2048fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp    ping_file_depth,
2049faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
2050faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
2051faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
20524eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
20534eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
20544eb3931feb349dd87142c78503b779228f3e1a0fglennrp
20554eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
20564eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
20594383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
206098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_cHRM,
206198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_gAMA,
206298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_iCCP,
206398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_sRGB,
20643d627862fb79aad8a20be4f1587f0b8761db441aglennrp    ping_found_sRGB_cHRM,
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
206716ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
206816ea139d53d867211d3bb0fa859a83de653f687ecristy    transparent_color;
206916ea139d53d867211d3bb0fa859a83de653f687ecristy
207016ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
207116ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
207216ea139d53d867211d3bb0fa859a83de653f687ecristy
2073faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
2074faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
2075faa852bad40107edae19405e76a299057668d795glennrp
2076faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
2077faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
2078faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
2079faa852bad40107edae19405e76a299057668d795glennrp
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2090faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
2091faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
2092faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
20934eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
20944eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
2095faa852bad40107edae19405e76a299057668d795glennrp
209616ea139d53d867211d3bb0fa859a83de653f687ecristy  QuantumInfo
209716ea139d53d867211d3bb0fa859a83de653f687ecristy    *quantum_info;
209816ea139d53d867211d3bb0fa859a83de653f687ecristy
2099bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2100756ae430d36380dfab8ca703538f5922f3796351cristy    ping_rowbytes,
21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2106bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
211016ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
211439992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2117eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
2118eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
2119eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
212075fc68f33e6e766a22e8ed653c3ed50b0d142827cristy  unsigned char
212175fc68f33e6e766a22e8ed653c3ed50b0d142827cristy    *volatile ping_pixels;
212255b78b53f1e013e0af19565ac04aaa7660d53795cristy
2123629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
2132629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_APNG_SUPPORTED /* libpng was built with APNG patch; */
2133629960f505ebba710ec9b6953a539a21dab176f2glennrp                          /* ignore the APNG chunks */
2134629960f505ebba710ec9b6953a539a21dab176f2glennrp     97,  99,  84,  76, (png_byte) '\0',   /* acTL */
2135629960f505ebba710ec9b6953a539a21dab176f2glennrp    102,  99,  84,  76, (png_byte) '\0',   /* fcTL */
2136629960f505ebba710ec9b6953a539a21dab176f2glennrp    102, 100,  65,  84, (png_byte) '\0',   /* fdAT */
2137629960f505ebba710ec9b6953a539a21dab176f2glennrp#endif
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
2142fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2144d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
2145d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
2146d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
2147d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
2148d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
2149ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         MagickLibVersionText,32);
2150d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
2151ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         MagickLibAddendum,32);
2152ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
2153d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
2154d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
2155ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
2156ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
2157ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
2158ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
2159ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
2160d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
2161d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
2162ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
2163ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
2164ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
2165ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
2166ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
2167d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  if (logging)
2168d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
2169d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    IM version     = %s",
2170d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           im_vers);
2171d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Libpng version = %s",
2172d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           libpng_vers);
2173ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(libpng_vers,libpng_runv) != 0)
2174ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
2175ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
2176ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           libpng_runv);
2177ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
2178d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
2179d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           zlib_vers);
2180ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(zlib_vers,zlib_runv) != 0)
2181ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
2182ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
2183ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           zlib_runv);
2184ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
2185d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
2186d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
218725c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
219361b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
219461b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
219561b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
219661b4c957269727a0a2526edc2331881da8346100glennrp    {
219761b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
219861b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
219961b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
220061b4c957269727a0a2526edc2331881da8346100glennrp    }
220161b4c957269727a0a2526edc2331881da8346100glennrp#  endif
220261b4c957269727a0a2526edc2331881da8346100glennrp#endif
220361b4c957269727a0a2526edc2331881da8346100glennrp
220416ea139d53d867211d3bb0fa859a83de653f687ecristy
220516ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info = (QuantumInfo *) NULL;
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2208a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
220998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
2210a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2211ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp      "    Before reading:");
22123d627862fb79aad8a20be4f1587f0b8761db441aglennrp
22133d627862fb79aad8a20be4f1587f0b8761db441aglennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2214ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp      "      image->alpha_trait=%d",(int) image->alpha_trait);
2215a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
221698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2217ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp      "      image->rendering_intent=%d",(int) image->rendering_intent);
2218e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
2219e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2220ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp      "      image->colorspace=%d",(int) image->colorspace);
22213d627862fb79aad8a20be4f1587f0b8761db441aglennrp
22223d627862fb79aad8a20be4f1587f0b8761db441aglennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2223ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp      "      image->gamma=%f", image->gamma);
222498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  }
222598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  intent=Magick_RenderingIntent_to_PNG_RenderingIntent(image->rendering_intent);
222698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
22270e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
22280e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
22290e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
22300e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
223116ea139d53d867211d3bb0fa859a83de653f687ecristy  transparent_color.alpha=65537;
22320e319739731741c52a6303723e0c8678a0df5579glennrp
2233913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp  number_colors=0;
2234cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
22354eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
2236cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
2237cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
223898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_cHRM = MagickFalse;
223998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_gAMA = MagickFalse;
224098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_iCCP = MagickFalse;
224198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_sRGB = MagickFalse;
224298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
224716ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
224816ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
224916ea139d53d867211d3bb0fa859a83de653f687ecristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
2250cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
2251cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
225316ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,&error_info,
2254cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
22600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
22680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2275cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
22760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2277faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2283edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2284edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
2285cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2287edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2288edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (ping_pixels != (unsigned char *) NULL)
2289edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
2290edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
22940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
22967b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
229716ea139d53d867211d3bb0fa859a83de653f687ecristy          InheritException(exception,exception);
22987b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
22997b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
23000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2303edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2304edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
2305edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
2306edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
2307edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
2308edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2309edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
2310edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
2311edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
2312edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2313a3a5f956194e91458e2789966ad15308e8f3df47glennrp#if PNG_LIBPNG_VER >= 10400
2314a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
2315a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
2316a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
2317a3a5f956194e91458e2789966ad15308e8f3df47glennrp
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2321faa852bad40107edae19405e76a299057668d795glennrp
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
23240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
23492ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#if PNG_LIBPNG_VER < 10700 /* Avoid libpng16 warning */
23502ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp  png_set_keep_unknown_chunks(ping, 2, NULL, 0);
23512ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#else
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
23532ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#endif
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23612feb141b6f74ce425fed3272286fab1f50366bb9glennrp#ifdef PNG_SET_USER_LIMITS_SUPPORTED
236209cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  if (PNG_LIBPNG_VER >= 10400)
23632feb141b6f74ce425fed3272286fab1f50366bb9glennrp    /* Limit the size of the chunk storage cache used for sPLT, text,
2364687361928f16a28ea56e200d00e970e68173cc25glennrp     * and unknown chunks.
23652feb141b6f74ce425fed3272286fab1f50366bb9glennrp     */
2366687361928f16a28ea56e200d00e970e68173cc25glennrp    png_set_chunk_cache_max(ping, 32767);
236709cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  endif
23682feb141b6f74ce425fed3272286fab1f50366bb9glennrp#endif
23692feb141b6f74ce425fed3272286fab1f50366bb9glennrp
23709bf97b6c2143eb20c330346b01e82102cc082725glennrp#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
23719bf97b6c2143eb20c330346b01e82102cc082725glennrp    /* Disable new libpng-1.5.10 feature */
23729bf97b6c2143eb20c330346b01e82102cc082725glennrp    png_set_check_for_invalid_index (ping, 0);
23739bf97b6c2143eb20c330346b01e82102cc082725glennrp#endif
23749bf97b6c2143eb20c330346b01e82102cc082725glennrp
2375991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2376991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2377991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2391991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2395faa852bad40107edae19405e76a299057668d795glennrp
2396faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2397faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2398faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2399faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2400faa852bad40107edae19405e76a299057668d795glennrp
2401fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp  ping_file_depth = ping_bit_depth;
2402fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp
24035830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  /* Save bit-depth and color-type in case we later want to write a PNG00 */
24045830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  {
24055830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      char
24065830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        msg[MaxTextExtent];
24075830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
24085830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_color_type);
24095830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) SetImageProperty(image,"png:IHDR.color-type-orig ",msg,exception);
24105830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
24115830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
24125830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) SetImageProperty(image,"png:IHDR.bit-depth-orig  ",msg,exception);
24135830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  }
24145830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2415faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2416faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2417faa852bad40107edae19405e76a299057668d795glennrp
2418faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2419faa852bad40107edae19405e76a299057668d795glennrp
2420faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2422fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       png_set_packing(ping);
2423fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       ping_bit_depth = 8;
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2425faa852bad40107edae19405e76a299057668d795glennrp
2426faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
24273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2428faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
242998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2430176b29a003f11fd934137871d574995319408665cristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2431176b29a003f11fd934137871d574995319408665cristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2432176b29a003f11fd934137871d574995319408665cristy    {
2433176b29a003f11fd934137871d574995319408665cristy      image->rendering_intent=UndefinedIntent;
243498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      intent=Magick_RenderingIntent_to_PNG_RenderingIntent(UndefinedIntent);
2435176b29a003f11fd934137871d574995319408665cristy      image->gamma=1.000;
2436176b29a003f11fd934137871d574995319408665cristy      (void) ResetMagickMemory(&image->chromaticity,0,
2437176b29a003f11fd934137871d574995319408665cristy        sizeof(image->chromaticity));
2438176b29a003f11fd934137871d574995319408665cristy    }
243998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2443e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
2444e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
24450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
2448faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
24490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
2452faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
24530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
2456faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
245998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
246098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
246198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_gAMA=MagickTrue;
246298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
246398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
246498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG gAMA chunk.");
246598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
246698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
246798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
246898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
246998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_cHRM=MagickTrue;
247098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
247198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
247298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG cHRM chunk.");
247398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
247498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
247598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
247698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
247798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_iCCP=MagickTrue;
247898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
247998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
248098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG iCCP chunk.");
248198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
248298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
248398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
248498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
248598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_sRGB=MagickTrue;
248698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
248798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
248898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG sRGB chunk.");
248998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
249098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2491faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2492faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2497e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2498e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2499e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2500e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2501e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2502e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2503e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2504e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
25130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
2522e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          profile=BlobToStringInfo(info,profile_length);
2523e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          if (profile == (StringInfo *) NULL)
2524edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2525edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              png_warning(ping, "ICC profile is NULL");
2526edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              profile=DestroyStringInfo(profile);
2527edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2528edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp          else
2529edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2530edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              (void) SetImageProfile(image,"icc",profile,exception);
2531edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              profile=DestroyStringInfo(profile);
2532edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
25392ea7a8e883de7623d345f32f90ee99248a4a867ecristy      {
25402ea7a8e883de7623d345f32f90ee99248a4a867ecristy        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
25412ea7a8e883de7623d345f32f90ee99248a4a867ecristy          (mng_info->global_srgb_intent);
25422ea7a8e883de7623d345f32f90ee99248a4a867ecristy      }
25430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2546cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
2547cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
25480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2551e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2556faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2557faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2558faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
25590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
256898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2569faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2570faa852bad40107edae19405e76a299057668d795glennrp    {
2571faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2572faa852bad40107edae19405e76a299057668d795glennrp        {
2573faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2574faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2575faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2576faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2577faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2578faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2579faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2580faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2581faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2582faa852bad40107edae19405e76a299057668d795glennrp        }
2583faa852bad40107edae19405e76a299057668d795glennrp    }
25840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2585faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
25960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25973d627862fb79aad8a20be4f1587f0b8761db441aglennrp       if (image->chromaticity.red_primary.x>0.6399f &&
25983d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
25993d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
26003d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
26013d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
26023d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
26033d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
26043d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
26053d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
26063d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
26073d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
26083d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
26093d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
26103d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
26113d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
26123d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f)
26133d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_sRGB_cHRM=MagickTrue;
26143d627862fb79aad8a20be4f1587f0b8761db441aglennrp
26155cf1bff142633838354b1080183c957900bc80e8glennrp      ping_found_cHRM=MagickTrue;
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2618e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26203d627862fb79aad8a20be4f1587f0b8761db441aglennrp      if (ping_found_sRGB != MagickTrue &&
26213d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_gAMA != MagickTrue ||
262284288238d90b2e1831857d6b2427abd7875b7e1bglennrp          (image->gamma > .45 && image->gamma < .46)) &&
26233d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_cHRM != MagickTrue ||
26243d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_sRGB_cHRM == MagickTrue) &&
26253d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_iCCP != MagickTrue)
26265cf1bff142633838354b1080183c957900bc80e8glennrp      {
26275cf1bff142633838354b1080183c957900bc80e8glennrp         png_set_sRGB(ping,ping_info,
26285cf1bff142633838354b1080183c957900bc80e8glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent
26295cf1bff142633838354b1080183c957900bc80e8glennrp            (image->rendering_intent));
26305cf1bff142633838354b1080183c957900bc80e8glennrp         file_gamma=1.000f/2.200f;
26315cf1bff142633838354b1080183c957900bc80e8glennrp         ping_found_sRGB=MagickTrue;
263284288238d90b2e1831857d6b2427abd7875b7e1bglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2633918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp           "    Setting sRGB as if in input");
26345cf1bff142633838354b1080183c957900bc80e8glennrp      }
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26365cf1bff142633838354b1080183c957900bc80e8glennrp
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2638faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2640905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2641905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
26420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2646e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2647e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2651faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2652faa852bad40107edae19405e76a299057668d795glennrp    {
2653faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2654faa852bad40107edae19405e76a299057668d795glennrp        {
2655faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2656faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2657faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2658faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2659faa852bad40107edae19405e76a299057668d795glennrp        }
2660faa852bad40107edae19405e76a299057668d795glennrp    }
2661faa852bad40107edae19405e76a299057668d795glennrp
2662faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
26680881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
266916ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.x=(double) x_resolution;
267016ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.y=(double) y_resolution;
26710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
267516ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.x=(double) x_resolution/100.0;
267616ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.y=(double) y_resolution/100.0;
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2681e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2682e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2685823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2686faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
26920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2694faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
27000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2701faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2702edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              {
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
2705edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                    png_warning(ping,
2706edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                      "global tRNS has more entries than global PLTE");
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2708edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                else
2709edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  {
2710edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                     png_set_tRNS(ping,ping_info,mng_info->global_trns,
2711edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                       (int) mng_info->global_trns_length,NULL);
2712edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  }
2713edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               }
2714bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2719faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2728faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2729faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
27300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
27330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
27353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
27360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
27390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2740c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2741c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2742c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2748edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"No global PLTE in file");
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2752bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2753faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2754faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
27560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2757faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2759bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2760bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2761bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
27680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2769bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      /* Scale background components to 16-bit, then scale
2770bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2771bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
2772bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2773bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2774bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    raw ping_background=(%d,%d,%d).",ping_background->red,
2775bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            ping_background->green,ping_background->blue);
27762cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2777bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
27780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2779fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth == 1)
2780bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
27810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2782fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 2)
2783bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
27840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2785fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 4)
2786bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
27870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2788fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth <= 8)
2789bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
27902cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2791bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2792bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2793bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
27942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2795bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2796bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
27972cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27982cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
27990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28002cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28012cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
28022cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
2803bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
28042cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2805bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2806faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
28070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2808bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2809faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
28100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2811bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2812bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
28130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
281416ea139d53d867211d3bb0fa859a83de653f687ecristy        image->background_color.alpha=OpaqueAlpha;
28152cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2816bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2817bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2818bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2819bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2820bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2821bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2823bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2824a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2825faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2828a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
283335ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
283435ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
283535ef824baa82511126ff0072ae30eee0da9c05a3cristy
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2840fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      max_sample = (int) ((one << ping_file_depth) - 1);
28413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2842faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2843faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2844faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2845faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2846faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2847faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2853faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
28548a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          image->alpha_trait=UndefinedPixelTrait;
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2858a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2859a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2860a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2861fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale_to_short = 65535L/((1UL << ping_file_depth)-1);
2862a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2863a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2864a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2865a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2866a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
286716ea139d53d867211d3bb0fa859a83de653f687ecristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
286805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2869faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28710f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
28720f111984738842d27d04aed2a3f823d82a943506glennrp              {
28730f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28740f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
28750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28760f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
287716ea139d53d867211d3bb0fa859a83de653f687ecristy                  "    scaled graylevel is %.20g.",transparent_color.alpha);
28780f111984738842d27d04aed2a3f823d82a943506glennrp              }
287916ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.red=transparent_color.alpha;
288016ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.green=transparent_color.alpha;
288116ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.blue=transparent_color.alpha;
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
28863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2888faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2893faa852bad40107edae19405e76a299057668d795glennrp
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2895faa852bad40107edae19405e76a299057668d795glennrp
2896faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2897faa852bad40107edae19405e76a299057668d795glennrp
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
29003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2902bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2904bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2907faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2908faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2919faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2920faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2921a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
292216ea139d53d867211d3bb0fa859a83de653f687ecristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
292316ea139d53d867211d3bb0fa859a83de653f687ecristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
29248d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    {
2925e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp      if ((!png_get_valid(ping,ping_info,PNG_INFO_gAMA) ||
29263d627862fb79aad8a20be4f1587f0b8761db441aglennrp          image->gamma == 1.0) && ping_found_sRGB != MagickTrue)
29278d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        {
29288d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          /* Set image->gamma to 1.0, image->rendering_intent to Undefined,
2929e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp           * image->colorspace to GRAY, and reset image->chromaticity.
29308d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp           */
29318d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          SetImageColorspace(image,GRAYColorspace,exception);
29328d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        }
29338d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    }
2934e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
2935e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp  (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2936e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp      "  image->colorspace=%d",(int) image->colorspace);
2937a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
2938faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
293932340ffa74550819f755f966e397ed58bbccd8e5glennrp      ((int) ping_bit_depth < 16 &&
294032340ffa74550819f755f966e397ed58bbccd8e5glennrp      (int) ping_color_type == PNG_COLOR_TYPE_GRAY))
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2942befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2943befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2944befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2946befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2947fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      image->colors=one << ping_file_depth;
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
295067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
295167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
295267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
295367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2955faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2961bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
29620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
297416ea139d53d867211d3bb0fa859a83de653f687ecristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
2975edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
29760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2977faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
29830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29846af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
29906af6cf1a950b111ad0ac706269a703086693ba71glennrp
299167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
29926af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
29936af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
29946af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
29956af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
29966af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3001bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3004fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale=(QuantumRange/((1UL << ping_file_depth)-1));
30050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
30080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3009bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3017147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3018cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
3019cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
3020147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
3021147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
3022147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3023fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     /* encode ping_width, ping_height, ping_file_depth, ping_color_type,
3024147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
3025147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30263b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,
30277cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
302816ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.width,height    ",msg,exception);
3029147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3030fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_file_depth);
303116ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.bit_depth       ",msg,exception);
3032147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30335dff435eceea4f80207a906b11e65aed48fe3f27glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d (%s)",
30345dff435eceea4f80207a906b11e65aed48fe3f27glennrp         (int) ping_color_type,
30355dff435eceea4f80207a906b11e65aed48fe3f27glennrp         Magick_ColorType_from_PNG_ColorType((int)ping_color_type));
303616ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.color_type      ",msg,exception);
3037147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3038913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (ping_interlace_method == 0)
3039913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3040913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Not interlaced)",
3041913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3042913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3043913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else if (ping_interlace_method == 1)
3044913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3045913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Adam7 method)",
3046913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3047913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3048913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else
3049913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3050913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Unknown method)",
3051913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3052913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3053913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
3054913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp
3055913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (number_colors != 0)
3056913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3057913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d",
3058913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) number_colors);
3059913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) SetImageProperty(image,"png:PLTE.number_colors   ",msg,
3060913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            exception);
3061913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3062cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3063147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
30690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30700ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
3071347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
3072347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30741b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
30751b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
30761b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
30771b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3080e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3083edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3084edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
3085cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3087edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
30910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
30980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
3100cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
3101cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
31020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
3104cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
3105cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
31060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3107cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
3108edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation failed");
31090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
311616ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info=AcquireQuantumInfo(image_info,image);
311716ea139d53d867211d3bb0fa859a83de653f687ecristy
311816ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
3119edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping,"Failed to allocate quantum_info");
31200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31214b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
31224b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp
3123c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
3124c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3125c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
3126c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
3127c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3128c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
3129c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3132c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
3133c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3134c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
3135c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
3136c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
31378a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
3138c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
3139c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3140b0a657e13c4aefba39c51292005427b47277869dcristy            BlendPixelTrait : UndefinedPixelTrait;
31410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3142c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
3143c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
3144c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
3145c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
31460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3147c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
3148c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
31490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3150cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
3151c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3152c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          if (pass < num_passes-1)
3153c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp            continue;
3154c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3155862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
315716ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
3158c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
31590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
316016ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
316116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
316216ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
31630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
316416ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
316516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
316616ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
31670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
316816ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
316916ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
317016ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
31710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
317216ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
317316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
317416ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
31750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
317616ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
317716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
317816ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
31793faa9a3fb01696daaf976d595f492cb530bffb21glennrp
3180c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
3181c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3182c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
3183a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
3184a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3185a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
3186a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3187c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3188c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
31895aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
31905aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
319116ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
3192c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
3193a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3194a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3195a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
3196a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3197c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
3198c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
3199c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
32004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
32014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
320216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
320316ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
320416ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
320516ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
320616ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
320716ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
32084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
3209a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3210a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3211a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
32124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
32134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
32144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
321516ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
3216c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
3217c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
32180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3219c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
3220c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3221c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
3222c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
32230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3224c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
3225c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
3226c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
3227c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
3228c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
3229c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
32300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3231c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
32327a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3233c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
32347a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
32357a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
32367a287bfadeadea12e47c2376ca78a5d101687142cristy          }
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3241c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3253c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3254c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3255c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
325616ea139d53d867211d3bb0fa859a83de653f687ecristy
32578a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
3258b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
32590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
3261b0a657e13c4aefba39c51292005427b47277869dcristy        (image->alpha_trait  == BlendPixelTrait?  2 : 1)*
3262b0a657e13c4aefba39c51292005427b47277869dcristy        sizeof(*quantum_scanline));
32630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
3265edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
32660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3267bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32694f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        Quantum
32704f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp           alpha;
32714f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3273faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3274c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3277c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3278cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
3279c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3280c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp        if (pass < num_passes-1)
3281c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          continue;
3282c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
32834f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
32840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
328516ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
32870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3288cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3290c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3291faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
32954f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
3296faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3297bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3299a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33004f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33014f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                alpha=ScaleCharToQuantum((unsigned char)*p++);
33024f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33034f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                SetPixelAlpha(image,alpha,q);
33044f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33054f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                if (alpha != OpaqueAlpha)
33060b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
33074f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
330816ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3312bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3313a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
331747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3321a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
3322c17d96f447438bb27d874f1440ed05f6493fde1fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
332358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              size_t
332458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
332558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
332658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3327c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
332858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
332958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3330c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
333158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
333258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3333c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
333458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
33350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3336faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3338c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3339c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3340c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3341c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3342c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3343c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
33444f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33454f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  alpha=ScaleShortToQuantum(quantum);
33464f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  SetPixelAlpha(image,alpha,q);
33474f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33484f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  if (alpha != OpaqueAlpha)
334958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
33504f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
335116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
335258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
335358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
335458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
335558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
335658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
335747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
335858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
335958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
336016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
33614f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
336216ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
33630b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
33644f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
336558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
336616ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3369a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
337047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
337347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
33773faa9a3fb01696daaf976d595f492cb530bffb21glennrp
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
33820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
338316ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
338416ea139d53d867211d3bb0fa859a83de653f687ecristy
338516ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
338616ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3387bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
338816ea139d53d867211d3bb0fa859a83de653f687ecristy        {
338916ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
339016ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
339116ea139d53d867211d3bb0fa859a83de653f687ecristy        }
33920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
33950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33967a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
33977a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3398cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
33999fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
340047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34017a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
34027a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
34037a287bfadeadea12e47c2376ca78a5d101687142cristy          }
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3405c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
34067a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
340947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3413c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3416c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3417b0a657e13c4aefba39c51292005427b47277869dcristy    image->alpha_trait=found_transparent_pixel ? BlendPixelTrait :
3418b0a657e13c4aefba39c51292005427b47277869dcristy      UndefinedPixelTrait;
3419c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3420c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3421c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3422c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3423c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3424c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3425c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
34265aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
34275aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3429bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
34305aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
34315aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3432c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3433c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3434c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
343516ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
343616ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
343716ea139d53d867211d3bb0fa859a83de653f687ecristy
34385c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
34395c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3440b0a657e13c4aefba39c51292005427b47277869dcristy      PixelTrait
3441b0a657e13c4aefba39c51292005427b47277869dcristy        alpha_trait;
34425c6f789db7a30bad01ace12b09ad9cd471339e94cristy
3443b0a657e13c4aefba39c51292005427b47277869dcristy      alpha_trait=image->alpha_trait;
34448a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
344516ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3446b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait=alpha_trait;
34475c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
344847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34494eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3455cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
345716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
3458edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
3459cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
346647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3467faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
34768a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=BlendPixelTrait;
3477c11cf6a442f3046940608a5743a68cc891deb13eglennrp
34783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3479c11cf6a442f3046940608a5743a68cc891deb13eglennrp
34800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
34810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
34820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3483c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
34840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
34850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
34868a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                 image->colormap[x].alpha_trait=BlendPixelTrait;
348716ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
348816ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
34890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3490c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
349147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
34930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
34940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
34950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
34960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
349716ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
34980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
34998a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->colormap[x].alpha_trait=BlendPixelTrait;
350016ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
35010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
35020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
35030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
350416ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
35050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
350647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3507a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3508a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3509a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
35100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
35110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
35130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
35140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
35150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3516c11cf6a442f3046940608a5743a68cc891deb13eglennrp
351716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
35180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3519c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3521a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3522a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3523a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
35240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
35250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
352616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
352716ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
352816ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
352916ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
353016ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
353116ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
35324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
353316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
35344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
35350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
353667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
35370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
35384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
353916ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
35404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3541a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
35420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
354316ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
35440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
35450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
35470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3548c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
35490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3550a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3551c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35543c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3555eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
35564eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
35574eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3558a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3559a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
35604eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3561a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3562a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35644eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
35654eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
35664eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
35674eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
35680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35694eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
35704eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35714eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
35720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35734eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
35744eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
3575edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            (void) Magick_png_read_raw_profile(ping,image,image_info,text,
3576edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               (int) i,exception);
35774eb3931feb349dd87142c78503b779228f3e1a0fglennrp            num_raw_profiles++;
35784eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
35794eb3931feb349dd87142c78503b779228f3e1a0fglennrp
35804eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
35814eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
35824eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
35834eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
35844eb3931feb349dd87142c78503b779228f3e1a0fglennrp
35854eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
35864eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
35874eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
35884eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
35894eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
3590edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"Memory allocation failed");
35914eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
35924eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
35934eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
35944eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
35954eb3931feb349dd87142c78503b779228f3e1a0fglennrp
35964eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
35974eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
35984eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
35994eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
36004eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
36014eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
360216ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36044eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36064eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36074eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      length: %lu",(unsigned long) length);
36084eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36094eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      Keyword: %s",text[i].key);
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36124eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
361397f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
36144eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
36154eb3931feb349dd87142c78503b779228f3e1a0fglennrp      num_text_total += num_text;
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36173c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
363073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
36310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
363847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
3643edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp             png_error(ping,"Memory allocation failed");
36440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
3646edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping,"Cannot overwrite frozen MNG object buffer");
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
36480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
36550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
365716ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
36580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
36610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
3663edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping, "Cloning image for object buffer failed");
36640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3665faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
36670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3668faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3669faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3670faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3671faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3672faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3673faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3674faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3675faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
36760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3677faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
36873c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
369347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
36990a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
37008a46d827a124555f0c48fb2368ec1bba8e079ab6cristy   /* Set image->alpha_trait to MagickTrue if the input colortype supports
37010a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
37020a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
37030a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
37048a46d827a124555f0c48fb2368ec1bba8e079ab6cristy    image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
37050a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
37060a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3707b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
37080a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3709224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#if 0  /* I'm not sure what's wrong here but it does not work. */
37105830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    if (image->alpha_trait == BlendPixelTrait)
37115830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37125830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
37135830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleMatteType,exception);
37145830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37155830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
37165830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteMatteType,exception);
37175830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37185830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
37195830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
37205830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
37215830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37225830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    else
37235830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37245830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
37255830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleType,exception);
37265830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37275830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
37285830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteType,exception);
37295830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37305830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
37315830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorType,exception);
37325830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
3733224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#endif
37345830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
3735cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3736cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3737cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3738cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3739cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
37404eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3741cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3742cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
37433b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3744613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
374516ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text                 ",msg,
374616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3747cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3748cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3749cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3750cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
37513b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3752cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
375316ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
375416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3755cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3756cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
375798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_cHRM != MagickFalse)
37585961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
37593b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
37605961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
376116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:cHRM                 ",msg,
376216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
37635961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3764cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3765cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
37665961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
37673b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
37685961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
376916ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:bKGD                 ",msg,
377016ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
37715961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
37725961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
37733b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%s",
37745961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3775cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
377698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#if defined(PNG_iCCP_SUPPORTED)
377798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_iCCP != MagickFalse)
377816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageProperty(image,"png:iCCP                 ",msg,
377916ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
378098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#endif
3781cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
37824eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
378316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageProperty(image,"png:tRNS                 ",msg,
378416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
37854eb3931feb349dd87142c78503b779228f3e1a0fglennrp
37864eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
378798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_sRGB != MagickFalse)
37884eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
37893b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
379098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            "intent=%d (%s)",
379198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            (int) intent,
379298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            Magick_RenderingIntentString_from_PNG_RenderingIntent(intent));
379316ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:sRGB                 ",msg,
379498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp                 exception);
37954eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
37964eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
37974eb3931feb349dd87142c78503b779228f3e1a0fglennrp
379898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_gAMA != MagickFalse)
37994eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38003b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
380116ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
380216ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
380316ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:gAMA                 ",msg,
380416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38054eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3806cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38074eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3808cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
38094eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38103b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
381107523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
38124eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
381316ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:pHYs                 ",msg,
381416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38154eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38164eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3817cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38184eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
38194eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
38204eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38213b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
38224eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
382316ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:oFFs                 ",msg,
382416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38254eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38264eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38274eb3931feb349dd87142c78503b779228f3e1a0fglennrp
382807523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
382907523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
383007523c7d2e40370804c2036295571e4b6426f94dglennrp       {
38313b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
383207523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
383307523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
383416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:vpAg                 ",msg,
383516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
383607523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3837cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3838cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3844cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
38490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3850edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
3851edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
3852edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
3853edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3854edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* }  for navigation to beginning of SETJMP-protected block, revert to
3855edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    Throwing an Exception when an error occurs.
3856edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
3857edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
387021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
387121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
388847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
389247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3895fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
389616ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
389947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
390247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
390747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3908dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
391047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
391573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
391647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
391947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
393047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
39370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
39410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
39450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
394847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
395047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
39560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
395947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
396072715f5c299a6482f8eb175070b056d77b74a43fcristy  if ((IssRGBColorspace(image->colorspace) != MagickFalse) &&
39613d627862fb79aad8a20be4f1587f0b8761db441aglennrp      ((image->gamma < .45) || (image->gamma > .46)) &&
39623d627862fb79aad8a20be4f1587f0b8761db441aglennrp           !(image->chromaticity.red_primary.x>0.6399f &&
39633d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
39643d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
39653d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
39663d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
39673d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
39683d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
39693d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
39703d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
39713d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
39723d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
39733d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
39743d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
39753d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
39763d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
39773d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f))
397872715f5c299a6482f8eb175070b056d77b74a43fcristy    SetImageColorspace(image,RGBColorspace,exception);
397972715f5c299a6482f8eb175070b056d77b74a43fcristy
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
398197f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
398297f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
398397f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
398497f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
398597f90e23c85b9c58387880125c29d8c99126f83aglennrp
398697f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
39880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40404383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
40414383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
40424383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
4043bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
406316ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4066bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
407016ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4081bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
4095fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
40980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
409916ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
41070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
410816ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
41090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
41120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
41400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
41430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4151e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
4152e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
41560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
415947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
41630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4167bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
41690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
417247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
417947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4187bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
4189bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
419547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
419847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
420347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4207f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
420847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4210f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
421147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
421447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
421847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
422247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
422647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
423047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
423447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
423847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
424447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
424747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
426373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
426447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
426747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
426916ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
42700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
42770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
42810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
428873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
42890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
429416ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
42950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
43060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
43100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
43130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
43220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
43250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
432803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
434547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
435247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
435547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
436447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4372bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
437403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
438947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
44090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
44398182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
44400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
44508182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
44518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
44528182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
44538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
44548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
44558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
44568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
445847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4467e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4468cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
4469da7803d6b1161960bc1e7db4d9718284c116fab8cristy            image->gamma=1.000f/2.200f;
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
447947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44885eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
44895eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
44900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
449747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
450816ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
450916ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
451316ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
451416ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4525fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
45380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
456116ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
456747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
45710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45723b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
45740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
45770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
45910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
45940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4595bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
459716ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
459916ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
460016ea139d53d867211d3bb0fa859a83de653f687ecristy    {
460116ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
460216ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
460316ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
460416ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
460516ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
460616ea139d53d867211d3bb0fa859a83de653f687ecristy    }
460747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
46110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
46130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
462403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
46280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
46300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
463316ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46353b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
46390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4641bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
464416ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
464647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46478a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             if (image->alpha_trait == BlendPixelTrait)
464816ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
464916ea139d53d867211d3bb0fa859a83de653f687ecristy               {
465016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
465116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
465216ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
465316ea139d53d867211d3bb0fa859a83de653f687ecristy               }
46540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
465616ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
465816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
465916ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
46608a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->alpha_trait=BlendPixelTrait;
466116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
466216ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
46640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
467647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
467747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
46830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
46850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
46860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
46870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
46880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
46890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
46910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
46920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
46930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
46940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
46950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
46970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
46980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
46990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
47040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
47080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
475021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
475121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
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 ReadJNGImage()");
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  if (LocaleCompare(image_info->magick,"JNG") != 0)
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
47810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
478247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
478347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
478547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47863b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
47880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
478947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
479047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
479273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
47930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
47960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
479747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
479847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
48060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
48140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
482247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
48340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48484383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
484921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
485021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
48514383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4858bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
487616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4889bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
491538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
491638ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
491738ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4918bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
494047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
494147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4947fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
494816ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
49510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
49540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
495847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
495947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
496047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
496173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
49620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
49650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
496647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
496747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
497747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
498147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
498247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4985bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4986bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
499047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5033e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
5034e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
50380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
50410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
50440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
504847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
505147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5052bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
505447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
50640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
506616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
50680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
50750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
507716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
50790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
508447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
50890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
50960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5102bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
51040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5105bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
51070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5111e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5113e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
51178182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
51180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
51210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
51250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
51280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
51328182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
51360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
51390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
51420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
514716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
514947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
515016ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
51510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
51540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
51620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51633b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy            (void) FormatLocaleString(page_geometry,MaxTextExtent,
5164e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
5165f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
51660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
5168bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
5170bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
51720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
51750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
51880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
51928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
51930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
51960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
52050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5207e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
52080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5210e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
521916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
52240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
522616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
5233edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  Instead of using a warning we should allocate a larger
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
523616ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
524516ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
52510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
52530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
52560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
52630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
52640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
52660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
52670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5271e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
5272f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
52730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5275e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
5276f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
52860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
52930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
52980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
53160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
53190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
533116ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
534247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
534547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
534647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
53520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5353bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
536035ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
53690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
53750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
537947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5385bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
539212560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5400bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
54100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
541747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
541847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54218182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
54228182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
54238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
54258182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
54278182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
54298182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
54318182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
54338182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
543847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
544247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5450e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5451cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
545647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
546047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5463fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
547047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
547347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
547716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
54800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
54830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
548747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
54910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
54950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
549847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
549947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
550147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5502bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
550447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
550647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
551847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55218182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
55228182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
55230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55248182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
55258182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
55260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5527bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5528bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
55290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
55320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5537e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
553947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5542bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5543bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
55440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5545bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5546bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
55470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5548bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5549bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
55500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
55530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5558e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
556047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
55660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5570e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5571e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
557247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
55800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5581bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
55830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5592e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5593e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
55940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
559847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
559916ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
560116ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
560247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
560947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
56140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
56240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
56328a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                image->alpha_trait=UndefinedPixelTrait;
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
563416ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
56350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5639e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5640e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
565747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
566947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
569347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
569447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5703bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5706bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
571847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5721bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
572547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
572647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5729bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
574647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
575647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
575747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
57588182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
57590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5762e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5763e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
57640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
57670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
577847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
578247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
579447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
58010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5805e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5806f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
580747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
58120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
581747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
583547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
583947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
584316ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
584647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
584947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
58660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
58690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
58720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
587916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
588347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
588947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
589547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
589847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
590447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
590747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
591347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
591647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
592247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
592547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
593147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
593447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
594047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
594347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
594947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
595347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
595716ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
596147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
598047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
598416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
598747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
599047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
599416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
599747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
600047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
600547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
60218182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
60238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
602747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
603416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
603647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
604247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
604416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
604747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
6050bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
6052bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
606047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
606347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
606647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
606947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
607247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
607547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
607847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
608647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
608947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
609247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
609747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
610747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
611447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
611747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
612347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
613147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61328182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
61338182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
6146bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
6148bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
615016ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
615516ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
615647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
616347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
616747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
617447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
617747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
617847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
617947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
618816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6191e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
6192e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
620316ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
620816ea139d53d867211d3bb0fa859a83de653f687ecristy              AcquireNextImage(image_info,image,exception);
620947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
621647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
62190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
62210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
623147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
62408a46d827a124555f0c48fb2368ec1bba8e079ab6cristy            image->alpha_trait=UndefinedPixelTrait;
624116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
62420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6246e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6247e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
625147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
625216ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
625716ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
625847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
626547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
62710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
62740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
62830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
62920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
629847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
630247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
630747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6308bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
630947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
632147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
633447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
636747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
637047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
637247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
637347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
637547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63784e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
637947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
638247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
638547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
638747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
638847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
639047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
639447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
639747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
639947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
640047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
640247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64054e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
640647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
640947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
641247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
641447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
641547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
641747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
642716ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
642816ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
642916ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
643016ea139d53d867211d3bb0fa859a83de653f687ecristy
643116ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
643216ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
643316ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
643416ea139d53d867211d3bb0fa859a83de653f687ecristy
6435bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
643916ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
644316ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
644416ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
644647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
644747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
645147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
645216ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
645347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64693faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
648147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6482bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
648416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
648516ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
648616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
648716ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
648816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
648916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
649016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
649116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
649216ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
649447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65038a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                if (image->alpha_trait == BlendPixelTrait)
650416ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
650547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
650816ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
650916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
651047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
651347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
651647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
651947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6528e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6529bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
653116ea139d53d867211d3bb0fa859a83de653f687ecristy                length=(size_t) image->columns*GetPixelChannels(image);
653216ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
653316ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
653447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
653516ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
653616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
654347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
654647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6547bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
655147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6552bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6553bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
655447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6555bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6556bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
655747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6558bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
656047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6562bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
656347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
656747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6568bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
657447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
657716ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
65849fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
658516ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
658616ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
658747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6590fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6599bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
660016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
660116ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
660216ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
660316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
660416ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
660516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
660616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
660847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6612bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
661316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
661416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
661516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
661616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
661716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
661816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
661916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
662016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6621bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
662247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
662616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
662716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
662816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6629bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
663016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
663116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
663216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
663316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6634bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
663516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
663616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
663716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
663816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6639bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
664016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
664147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66428a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                              if (image->alpha_trait == BlendPixelTrait)
664316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
664416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
664516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6646bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
664716ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
664947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
665416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
665516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
665716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
665816ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
666147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6666bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
666716ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
666816ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
666916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
667016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
667116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
667216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
667316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
667416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6675bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
667647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6678bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
667916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
668016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
668116ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
668216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
668316ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
668416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
668516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6686bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
668747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
669016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
669116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
669216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6693bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
669416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
669716ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
669816ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
669916ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
670147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
670447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
670747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
670816ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
670916ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6726e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6728bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
673016ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
673416ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
673516ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
673647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6737bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6738bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
674016ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
67417c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6742bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6743bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
674447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6745bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6746bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
674747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6749bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
675047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6751bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
675347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6755bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
675647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
676216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
676316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
676416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
676516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
676747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6771bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
677216ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
677316ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
677416ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
677516ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6776bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
677747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
677816ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
678216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
678316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
678416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6785bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
678616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6787bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
678816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
678916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
679016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6791bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
679216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6793bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
679416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
679516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
679616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6797bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
679816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
67998a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                              if (image->alpha_trait == BlendPixelTrait)
680016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
680116ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
680216ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6803bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
680416ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
680647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6811bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
681216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
681316ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6814bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6816bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
681716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
681816ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6819bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
682247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6827bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
682816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
682916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
683016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
683116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6832bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
683347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6835bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
683616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
683716ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
683816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
683916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6840bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
684147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
684516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
684616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
684716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6848bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
684916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
685216ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
685416ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
685516ea139d53d867211d3bb0fa859a83de653f687ecristy                    p+=GetPixelChannels(image);
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
685747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68613faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6867bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
687047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6871bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
687316ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
687416ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
687516ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
687616ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
687716ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
687816ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
687916ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
688016ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
688116ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
688347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
69083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
691747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6933bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6934bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
694047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
695247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
696316ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69752b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69762b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
697716ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
69782b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
69792b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
69802b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
69812b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
69822b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
69833faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
6984cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
6985cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
6986cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
6987cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
6988cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
6989cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
699016ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
69918640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6993d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6997bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7000d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
7004d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
700647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
700847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
701247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
70230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
702416ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
702916ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
703447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
703847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
70508a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
70510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
705316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
70540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
70590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
70620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
707047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
707116ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
707447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
70790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
708447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
708516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
709047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
709847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
709916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
710347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
710947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
711016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
711247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
711547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
71230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
71260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
71290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
713447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
71400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
71420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7145e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
7146e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
71470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
715547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
715847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7160e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
716147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7166e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7178bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
718347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
718516ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
718647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
718947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
719247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
720147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
720447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
722147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
723147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
723447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7236e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
7237e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
723847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7240f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7241f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
724247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7243f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7244e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7245e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7246f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7247f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
724847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
725247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
725547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
725825c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
726347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
726647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
726947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
727425c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7297bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7300bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
731347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
731947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
732747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
733147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
733947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
734247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
734747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
735047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
735347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
735947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
736447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
736947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
737247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
737747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
738247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
739247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
739647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
740347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
740647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
741147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
7414fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or binary transparent 24-bit RGB");
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
741947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
742447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7431fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry=SetMagickInfo("PNG48");
7432fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7433fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7434fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7435fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7436fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7437fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7438fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
7439fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->adjoin=MagickFalse;
7440fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or binary transparent 48-bit RGB");
7441fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->module=ConstantString("PNG");
7442fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7443fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7444fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry=SetMagickInfo("PNG64");
7445fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7446fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7447fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7448fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7449fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7450fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7451fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
7452fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->adjoin=MagickFalse;
7453fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or transparent 64-bit RGBA");
7454fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->module=ConstantString("PNG");
7455fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7456fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
74575830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry=SetMagickInfo("PNG00");
74585830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
74595830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
74605830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74615830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74625830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#endif
74635830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
74645830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
74655830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->adjoin=MagickFalse;
74666270857991c1a3fb1d05e652e81835ee4fcf0a34glennrp  entry->description=ConstantString(
74676270857991c1a3fb1d05e652e81835ee4fcf0a34glennrp    "PNG inheriting bit-depth and color-type from original");
74685830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->module=ConstantString("PNG");
74695830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) RegisterMagickInfo(entry);
74705830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
747247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
747947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
74833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
748647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7487edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
7488cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
748918b17443128598500357da7bff2f01683cf32890cristy#endif
749047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
74933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
75003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
75093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
7520fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG48");
7521fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG64");
75225830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) UnregisterMagickInfo("PNG00");
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
752447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7525edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
7526cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
7527cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
753225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
755116ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
755216ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
756016ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7610cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7617bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
76380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
76390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
76410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7642a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
7643a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
7644a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7645a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
7646a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
7650a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
7651a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping,
7652a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy      (png_alloc_size_t) allocated_length);
7653a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
7654a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7655a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
7656a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
7657a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
76693b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7670f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
767247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7673bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
76773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
768047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
76843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
768747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
769047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
76943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7696cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
76974383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
771147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
771247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
771347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
771547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7719cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
772147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
772247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
772347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
772447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
772547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
772647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7727cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7728cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7729cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
773047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
773147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
773247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
773347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
773447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
773547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
773647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7737cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
773847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
774047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
774347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7747b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7748b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
775016ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
775216ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
775316ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
775416ea139d53d867211d3bb0fa859a83de653f687ecristy
775516ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
775616ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
775716ea139d53d867211d3bb0fa859a83de653f687ecristy
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
77593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
77673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7771cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7772cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7773e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7774e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
77755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
777639992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
777739992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
77805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
77815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
77825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
77833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
77873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
77883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
77905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
77915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
77925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
77943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
77953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
779758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
779821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
779958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
780058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7801da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7802fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7803d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
78048d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
780539992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7806991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7807918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_iCCP,
7808991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7809918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_sRGB,
7810991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
781126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
781226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
781326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7814a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7815e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
781626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
781726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
781826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
781926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
782026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
782126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
782226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7823e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
782426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
782526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
782626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
782726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
78288d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
78290e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
78300e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
783182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
78328ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7833d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7834d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
783916ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
784016ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
784116ea139d53d867211d3bb0fa859a83de653f687ecristy
7842bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
78433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
78443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
784775fc68f33e6e766a22e8ed653c3ed50b0d142827cristy    *volatile ping_pixels;
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7849d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  char
7850ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    im_vers[32],
7851ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    libpng_runv[32],
7852ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    libpng_vers[32],
7853ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    zlib_runv[32],
7854ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    zlib_vers[32];
7855d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
78565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7857f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
78580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
78595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
78605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
78615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
78625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
78635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
78645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7865bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
78665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
78675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7869bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7874dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7875fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7876f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
78778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
78788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
78798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7880dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7881dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7882dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7883dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7884dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7885dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
78863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7887fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
78883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
788916ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
789016ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
789116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
789216ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7893b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7894d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
7895d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
7896d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
7897d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
7898d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
7899d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp         MagickLibVersionText,MaxTextExtent);
7900d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
7901d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp         MagickLibAddendum,MaxTextExtent);
7902ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7903d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
7904d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
7905ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
7906ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
7907ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
7908ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
7909ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7910d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
7911d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
7912ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
7913ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
7914ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
7915ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
7916ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7917d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  if (logging)
7918d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
7919d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    IM version     = %s",
7920d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           im_vers);
7921d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Libpng version = %s",
7922d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           libpng_vers);
7923ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(libpng_vers,libpng_runv) != 0)
7924ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
7925ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
7926ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           libpng_runv);
7927ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
7928d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
7929d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           zlib_vers);
7930ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(zlib_vers,zlib_runv) != 0)
7931ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
7932ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
7933ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           zlib_runv);
7934ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
7935d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
7936d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
79375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
79380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
79395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
79405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
79415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
79425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
79435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
79445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
79455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
79465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
79475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
79485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
79495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
79505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
79515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
79525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
79535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
79545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
79555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7956dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
7957dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
7958dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
7959dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7960da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
7961f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp  ping_have_cheap_transparency=MagickFalse;
7962d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
79638d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
796439992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
7965991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
7966918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_iCCP=MagickFalse;
7967991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
7968918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_sRGB=MagickFalse;
7969991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
7970991d11dd9c33e65872778b81aff1347cd2878154glennrp
79710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
79720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
7973a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
7974dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
79750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
79760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
79770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
79780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
79790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
79800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
79810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7982dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
79830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
79840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
79850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
79860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79878d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
79880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
79890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79900d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
79910d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
79920d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
79930d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
79940d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
79950d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
79960d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   if (ping_exclude_sRGB == MagickFalse)
79970d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
79980d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
79990d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
80000d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80010d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
80020d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
80030d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80040d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
80050d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
80060d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
80070d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
80080d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80090d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
80100d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
80110d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
801216ea139d53d867211d3bb0fa859a83de653f687ecristy               (LocaleCompare(name,"ICM") == 0))
801316ea139d53d867211d3bb0fa859a83de653f687ecristy              {
8014ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
8015ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   icheck;
80160d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8017ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 /* 0: not a known sRGB profile
8018ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 1: HP-Microsoft sRGB v2
8019ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 2: ICC sRGB v4 perceptual
8020ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 3: ICC sRGB v2 perceptual no black-compensation
8021ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  */
80220d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 png_uint_32
8023ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   check_crc[4] = {0, 0xf29e526dUL, 0xbbef7812UL, 0x427ebb21UL},
8024ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   check_len[4] = {0, 3144, 60960, 3052};
80250d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8026ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
8027ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
8028ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   profile_crc;
802929a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8030ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
8031ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
80320d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8033ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
803429a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8035ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 for (icheck=3; icheck > 0; icheck--)
803629a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
8037ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   if (length == check_len[icheck])
8038ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
8039ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8040ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
8041ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
80420d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8043ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     data=GetStringInfoDatum(profile);
8044ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     profile_crc=crc32(0,data,length);
80450d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8046ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8047e54cd4b9aa386137b617b4b7fc66436c70466007glennrp                         "      with crc=%8x",(unsigned int) profile_crc);
8048ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
8049ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     if (profile_crc == check_crc[icheck])
8050ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
8051ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8052ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                            "      It is sRGB.");
8053ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
8054ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                          image->rendering_intent=PerceptualIntent;
8055ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
8056ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
805729a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
80580d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
8059ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 if (icheck == 0)
806029a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8061ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        "    Got a %lu-byte ICC profile",
806229a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
806329a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
80640d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
80650d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
80660d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
80670d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
80680d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
80708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
80718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
80728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8073fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
8074fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8075fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
8076fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8077fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
8078fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
8079fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8080fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
8081fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
8082fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8083fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
8084fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
808528af3713c9111a471cc868c787760de89236fa3cglennrp
8086750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  if (image->storage_class == PseudoClass &&
80877e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
8088fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png48 || mng_info->write_png64 ||
8089fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     (mng_info->write_png_colortype != 1 &&
8090fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png_colortype != 5)))
80917e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
809216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
80937e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
80947e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
80957e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
8096c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
809728af3713c9111a471cc868c787760de89236fa3cglennrp    {
8098c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
8099c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
8100c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
8101c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
8102c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8103c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
8104e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
8105c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
8106c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
810728af3713c9111a471cc868c787760de89236fa3cglennrp    }
8108bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
81093d9f5ba107b160e1819bb6baeeb3a9f521e9f450cristy  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
811016ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
81110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81123241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
81133241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
81143241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
81153241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
81163241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
811716ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
81183241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8119a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
8120a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
8121a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
8122a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
8123a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8124a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
8125a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8126a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
8127a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
8128a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
8129a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
81308e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
813167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < MAGICKCORE_QUANTUM_DEPTH)
813267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
813316ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
81348e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
81358e58efdecda887b08ef730d68290a61081ef2566glennrp
81368e58efdecda887b08ef730d68290a61081ef2566glennrp       if (image->depth > 8)
81378e58efdecda887b08ef730d68290a61081ef2566glennrp         {
81388e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 16
81398e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 16-bit */
814091d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR16PacketRGBO(image->background_color);
81418e58efdecda887b08ef730d68290a61081ef2566glennrp
81428e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
81438e58efdecda887b08ef730d68290a61081ef2566glennrp           {
814416ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
81458e58efdecda887b08ef730d68290a61081ef2566glennrp
814616ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
81478e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
81488e58efdecda887b08ef730d68290a61081ef2566glennrp
81498e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
81508e58efdecda887b08ef730d68290a61081ef2566glennrp             {
815116ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR16PixelRGBA(r);
815216ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
81538e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8154bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
81558e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
81568e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
81578e58efdecda887b08ef730d68290a61081ef2566glennrp           }
81588e58efdecda887b08ef730d68290a61081ef2566glennrp
81598e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
81608e58efdecda887b08ef730d68290a61081ef2566glennrp           {
81613e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
81628e58efdecda887b08ef730d68290a61081ef2566glennrp             {
816391d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR16PacketRGBO(image->colormap[i]);
81648e58efdecda887b08ef730d68290a61081ef2566glennrp             }
81658e58efdecda887b08ef730d68290a61081ef2566glennrp           }
81668e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 16 */
81678e58efdecda887b08ef730d68290a61081ef2566glennrp         }
81688e58efdecda887b08ef730d68290a61081ef2566glennrp
81698e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 4)
81708e58efdecda887b08ef730d68290a61081ef2566glennrp         {
81718e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 8
81728e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 8-bit */
817391d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR08PacketRGBO(image->background_color);
81748e58efdecda887b08ef730d68290a61081ef2566glennrp
81758e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
81768e58efdecda887b08ef730d68290a61081ef2566glennrp           {
817716ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
81788e58efdecda887b08ef730d68290a61081ef2566glennrp
817916ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
81808e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
81818e58efdecda887b08ef730d68290a61081ef2566glennrp
81828e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
81838e58efdecda887b08ef730d68290a61081ef2566glennrp             {
818416ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR08PixelRGBA(r);
818516ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
81868e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8187bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
81888e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
81898e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
81908e58efdecda887b08ef730d68290a61081ef2566glennrp           }
81918e58efdecda887b08ef730d68290a61081ef2566glennrp
81928e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
81938e58efdecda887b08ef730d68290a61081ef2566glennrp           {
81943e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
81958e58efdecda887b08ef730d68290a61081ef2566glennrp             {
819691d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR08PacketRGBO(image->colormap[i]);
81978e58efdecda887b08ef730d68290a61081ef2566glennrp             }
81988e58efdecda887b08ef730d68290a61081ef2566glennrp           }
81998e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 8 */
82008e58efdecda887b08ef730d68290a61081ef2566glennrp         }
82018e58efdecda887b08ef730d68290a61081ef2566glennrp       else
82028e58efdecda887b08ef730d68290a61081ef2566glennrp         if (image->depth > 2)
82038e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82048e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
820591d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
82068e58efdecda887b08ef730d68290a61081ef2566glennrp
82078e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82088e58efdecda887b08ef730d68290a61081ef2566glennrp           {
820916ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82108e58efdecda887b08ef730d68290a61081ef2566glennrp
821116ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82128e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82138e58efdecda887b08ef730d68290a61081ef2566glennrp
82148e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82158e58efdecda887b08ef730d68290a61081ef2566glennrp             {
821616ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
821716ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82188e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8219bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82208e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82218e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82228e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82238e58efdecda887b08ef730d68290a61081ef2566glennrp
82248e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82258e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82263e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82278e58efdecda887b08ef730d68290a61081ef2566glennrp             {
822891d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
82298e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82308e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82318e58efdecda887b08ef730d68290a61081ef2566glennrp         }
82328e58efdecda887b08ef730d68290a61081ef2566glennrp
82338e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
82348e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82358e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
823691d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
82378e58efdecda887b08ef730d68290a61081ef2566glennrp
82388e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82398e58efdecda887b08ef730d68290a61081ef2566glennrp           {
824016ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82418e58efdecda887b08ef730d68290a61081ef2566glennrp
824216ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82438e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82448e58efdecda887b08ef730d68290a61081ef2566glennrp
82458e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82468e58efdecda887b08ef730d68290a61081ef2566glennrp             {
824716ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
824816ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82498e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8250bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82518e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82528e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82538e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82548e58efdecda887b08ef730d68290a61081ef2566glennrp
82558e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82568e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82573e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82588e58efdecda887b08ef730d68290a61081ef2566glennrp             {
825991d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
82608e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82618e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82628e58efdecda887b08ef730d68290a61081ef2566glennrp         }
82638e58efdecda887b08ef730d68290a61081ef2566glennrp       else
82648e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82658e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
826691d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
82678e58efdecda887b08ef730d68290a61081ef2566glennrp
82688e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82698e58efdecda887b08ef730d68290a61081ef2566glennrp           {
827016ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82718e58efdecda887b08ef730d68290a61081ef2566glennrp
827216ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82738e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82748e58efdecda887b08ef730d68290a61081ef2566glennrp
82758e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82768e58efdecda887b08ef730d68290a61081ef2566glennrp             {
827716ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
827816ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82798e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8280bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82818e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82828e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82838e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82848e58efdecda887b08ef730d68290a61081ef2566glennrp
82858e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82868e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82873e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82888e58efdecda887b08ef730d68290a61081ef2566glennrp             {
828991d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
82908e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82918e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82928e58efdecda887b08ef730d68290a61081ef2566glennrp         }
8293cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
8294cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
829567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
829667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
829770e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
8298a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
82992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
83002b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
83012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
83022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
83038e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
83042b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
83052b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
83062b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83073faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
8308cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
8309cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
8310cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
8311cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
8312cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
8313cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
8314c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
831516ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
83168640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
83178640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
83188640fb5e9b1094f35f8beab436f81661b8a99448glennrp
8319a8036d6466b63ead629795b60772f160cca77c4cglennrp  if (image->storage_class != PseudoClass && mng_info->write_png_colortype &&
8320a8036d6466b63ead629795b60772f160cca77c4cglennrp     (mng_info->write_png_colortype > 4 || (mng_info->write_png_depth >= 8 &&
8321a8036d6466b63ead629795b60772f160cca77c4cglennrp     mng_info->write_png_colortype < 4 &&
8322a8036d6466b63ead629795b60772f160cca77c4cglennrp     image->alpha_trait != BlendPixelTrait)))
8323a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8324a8036d6466b63ead629795b60772f160cca77c4cglennrp     /* Avoid the expensive BUILD_PALETTE operation if we're sure that we
8325a8036d6466b63ead629795b60772f160cca77c4cglennrp      * are not going to need the result.
8326a8036d6466b63ead629795b60772f160cca77c4cglennrp      */
83272feb141b6f74ce425fed3272286fab1f50366bb9glennrp     image_colors = (int) image->colors;
83282feb141b6f74ce425fed3272286fab1f50366bb9glennrp     number_opaque = (int) image->colors;
8329a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (mng_info->write_png_colortype == 1 ||
8330a8036d6466b63ead629795b60772f160cca77c4cglennrp        mng_info->write_png_colortype == 5)
8331a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickFalse;
8332a8036d6466b63ead629795b60772f160cca77c4cglennrp     else
8333a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickTrue;
8334a8036d6466b63ead629795b60772f160cca77c4cglennrp     ping_have_non_bw=MagickFalse;
8335a8036d6466b63ead629795b60772f160cca77c4cglennrp
8336a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (image->alpha_trait == BlendPixelTrait)
8337a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8338a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 2;
8339a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 1;
8340a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8341a8036d6466b63ead629795b60772f160cca77c4cglennrp
8342a8036d6466b63ead629795b60772f160cca77c4cglennrp     else
8343a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8344a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 0;
8345a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 0;
8346a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8347a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
8348a8036d6466b63ead629795b60772f160cca77c4cglennrp
8349a8036d6466b63ead629795b60772f160cca77c4cglennrp  else
8350a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8351a8036d6466b63ead629795b60772f160cca77c4cglennrp  /* BUILD_PALETTE
8352a8036d6466b63ead629795b60772f160cca77c4cglennrp   *
8353a8036d6466b63ead629795b60772f160cca77c4cglennrp   * Normally we run this just once, but in the case of writing PNG8
8354e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
8355e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
83568ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
83578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
83588ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
83598ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
8360c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
836182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
83628ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
836382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
8364d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
836582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
83668ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
8367d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
8368a8036d6466b63ead629795b60772f160cca77c4cglennrp    /*
8369d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
8370d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
8371d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8372d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
8373d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
8374d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
8375d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8376d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8377d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
83788a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     * If image->alpha_trait is MagickFalse, we ignore the alpha channel
8379d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8380d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8381d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8382d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8383d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8384d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8385d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8386d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8387d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
83883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8389d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8390d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
83918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
839216ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8393d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8394d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8395d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
83968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
839716ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
839816ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8399d6bf1617e99df0272b231855a933a74e99b6578fglennrp
840016ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
840116ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8402fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8403fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8406d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8408d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8410d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84158a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             "      image->alpha_trait=%.20g",(double) image->alpha_trait);
841603812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
84183c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8419fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
84207ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
84217ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
84238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
842416ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
84252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
84277ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8433d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
843416ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
84357ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
84362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8439d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8441d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8443d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
844716ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
84512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8453d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
845483c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8455d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
845616ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
845716ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
84587ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
84598d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
84608d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84618d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
84637ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8465fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8466fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8467fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
84682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
84727ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
847316ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8474d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
847597fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
84788a46d827a124555f0c48fb2368ec1bba8e079ab6cristy           if (image->alpha_trait != BlendPixelTrait ||
847916ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
84808d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
84828d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
848516ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
848616ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8488d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8489d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
849216ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, opaque+i))
8493d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8495d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
849616ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
849916ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
850016ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85028d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85038d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
850416ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
85058d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8506d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
85078d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
851016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
851116ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
851216ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
851316ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
851416ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
851516ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
851616ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
851716ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
8518972d1c4895c4ee6da1b6745e1bb9cb71ee5d6d08cristy                         GetPixelGray(image,q);
8519d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8520d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8521d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8522d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8523d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
852416ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, transparent+i))
8525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8527d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8528d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8530d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8531d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
853216ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85348d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85358d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8536d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8537d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8538d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8540d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8541d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
854216ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85458d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8547d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
854816ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
854916ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
855016ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8552d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8554d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8555d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8556d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
855816ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
85618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
856216ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
85653c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
85664054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
85674054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8568d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8569d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8570d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8571d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8572c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8573c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8574c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8575c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8576c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8577c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8578c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8579c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8580d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8581d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8582ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8583ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8584ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8585ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8586d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8587d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
858803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
85898e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8590c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8591388a8c871db8f82488f34c4f41fc64a58b8cfbf7glennrp               number_opaque++;
8592c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8593c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8594c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8595c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8596c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8597c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
859803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8599a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8600a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8601a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8602d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86032cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8604d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
86053241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8606a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
8607a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
8608a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
8609a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
8610a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
8611a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
8612a080bc32a4a8b2ffec83fd836a28753959175363glennrp
8613d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8614d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8615d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8616d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8617d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
86183241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8619d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8620d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8621d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8622d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86233241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
86248d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
86258d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
86268d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8627fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8628d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8629d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
86300fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         ping_have_non_bw=MagickFalse;
86310fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
863298b95773e388844e22c6e4006bb88396b33cf6b4glennrp         if ((IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) ||
863398b95773e388844e22c6e4006bb88396b33cf6b4glennrp             (IssRGBColorspace(image->colorspace) != MagickFalse))
86340fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
86357fb2652ba366fc984d1dbb0c66560b91c57dab78cristy           ping_have_color=MagickTrue;
863698b95773e388844e22c6e4006bb88396b33cf6b4glennrp           ping_have_non_bw=MagickTrue;
86370fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
86380fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
8639d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8640d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8641d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8642d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8643d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
86446185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
864516ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8646d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
86476185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8648e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8649e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8650e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
865116ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
865216ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8653e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8654e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8655e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8656e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8657e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
865816ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8659e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8660e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8661e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8662e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8663e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8664d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8665d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8666d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
86676185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8668d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8669d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8670d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8671d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
86726185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
867316ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
867416ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8675d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8676d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8677e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8678d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
867916ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8680d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8681e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8682d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8683bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8684bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
86854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8686d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8687d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
868816ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8689d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8690bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8691d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8692d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8693d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8694d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8695d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8696d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8697d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8698d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8699d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8700d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8701d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
87023241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8703d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8704d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
87053241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8706d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8707d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8708d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8709d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8710d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8711d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8712c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8713c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8714bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8715d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8716d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8717d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8718d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8719d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8720d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8721d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8722d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8723d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8724d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8725d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8726d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8727d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8728d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8729d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8730d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8731d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8732d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8733d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8734d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8735d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8736d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
87373241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8738d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8739d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8740d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8741d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8742d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8743d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8744d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
87456185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8746d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8747d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8748d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8749d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
87502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8751d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8752d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8753d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8754d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8755d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8756d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
875716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8758d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
87593faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
87603faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8761d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8762d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8763d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8764d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8765d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8766d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8767d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8768d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8769d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8770bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8771d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8772d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8773d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8774d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8775fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8776fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8777d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8778d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
877916ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
87803c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
878116ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8782d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
87833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8784d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8785d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8786d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
878703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
87888a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                  if ((image->alpha_trait != BlendPixelTrait ||
878916ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
879016ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
879116ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
879216ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
87936185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
879416ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8795d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
87966185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
879703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
879816ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8799d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8800d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8801d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8802d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8803d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8804d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8805d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8806d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8807d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8808d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8809d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8810d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8811d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8812d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8813d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8814d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
881516ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
881683c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8817d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8818d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
881972988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8820d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8821d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8822d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8823d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8824d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8825d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8826d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
882716ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8828d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
88296185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
88306185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
88313c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8832d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8833d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8834d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8835d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8836d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
88373c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8838d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8839d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
88403c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8841d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8842d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8843d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8844d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
884503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8846d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8847d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8848d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
88496185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8850d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8851d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8852d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8853d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
88546185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8855d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8856d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8857d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8858a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8859d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8860d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8861d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8862a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8863d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8864d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8865d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8866d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8867d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8868d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8869d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
88706185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
887103812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
887203812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8873d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
88743c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8875c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8876c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8877fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8878c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8879c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8880c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8881c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8882c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8883c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8884fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8885c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8886130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8887130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8888130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8889c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8890130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8891c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8892c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8893c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8894fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8895c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8896c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
889716ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8898fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
889916ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8900c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8901fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8902c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8903c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
890416ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
89058ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
890616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelInfoPixel(image,&image->background_color,r);
890716ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
89088ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
89098ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
891016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
891116ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8912c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8913bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8914c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8915c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8916fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8917c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8918c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8919c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
892016ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
892116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
892216ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
8923c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8924c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8925c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8926c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8927c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8928e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8929e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8930e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8931c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8932d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8933d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8934d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8935d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8936d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8937d337164012450d70d62e71cf4a308a29004f7d57glennrp
8938d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8939d337164012450d70d62e71cf4a308a29004f7d57glennrp
894091d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8941d337164012450d70d62e71cf4a308a29004f7d57glennrp
8942d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8943d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8944d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8945d337164012450d70d62e71cf4a308a29004f7d57glennrp
8946d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8947d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8948d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8949d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
895016ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8951d337164012450d70d62e71cf4a308a29004f7d57glennrp
895216ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8953d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
8954d337164012450d70d62e71cf4a308a29004f7d57glennrp
8955d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
8956d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
895716ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
895854cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
895916ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8960d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
8961bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8962d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8963d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
8964d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8965d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8966d337164012450d70d62e71cf4a308a29004f7d57glennrp
8967d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
8968d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
8969d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8970d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
8971d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8972d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
89738e58efdecda887b08ef730d68290a61081ef2566glennrp
8974d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
8975d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
897691d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
8977d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8978d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8979d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
8980d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
8981d337164012450d70d62e71cf4a308a29004f7d57glennrp
898282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
898382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
898482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
898582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
898682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
898782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
898882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
898982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
899091d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
899182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
899282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
899382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8994e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
899582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
899682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
899782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
899882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
899982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
900016ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
900182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
900216ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
900382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
900482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
900582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
900682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
900716ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
900816ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
900916ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
901082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
9011bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
901282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
901382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
901482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
901582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
901682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
901782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
901882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
901982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
902082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
902182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9022e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
902382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
902482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
902591d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
902682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
9027d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9028d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
902982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
9030c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90318ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
9032c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
9033c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9034c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9035c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
9036c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90378ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
90388ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
90393faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
90403faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
90413faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
90423faa9a3fb01696daaf976d595f492cb530bffb21glennrp
904391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
9044fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9045c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9046c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9047e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
9048fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9049c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
9050c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9051c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
9052c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
905316ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
90548d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
905516ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
9056c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
9057c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
9058c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
9059c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
906016ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
906154cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
906216ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
9063c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
9064bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9065c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
9066c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
9067c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9068c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
9069c722dd852e8abe407c2846d39662f7ade9c234deglennrp
9070c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
9071c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
9072c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9073c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
9074c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9075e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
9076c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
9077c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
907891d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
9079c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9080c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
9081c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
9082c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
9083c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
90848ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
90858ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
90868ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
90878ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      /* Take care of special case with 256 colors + 1 transparent
90888ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
90898ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
90908ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
90918ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
90928ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
90938ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
90948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
90958ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
90968ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
90978ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
9098bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
90998ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
91008ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91018ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
91028ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
910316ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
9104bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
910516ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
91068ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
9107bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91088ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
91098ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
911016ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
911116ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
911216ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
911316ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
91148ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
911516ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
91168ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
911716ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
91188ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
9119bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91208ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
91218ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
9122bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91238ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
91248ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91258ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91268ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
91278ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91288ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
91298ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
91308ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
91318ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
91328ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
91338ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
91348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
91358ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
91368ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
91378ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91388ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
9139fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
9140a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
9141fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
9142fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9143fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
9144fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
9145fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
9146fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
91470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
91480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
91490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
9150d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
91510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
91530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
91540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
91560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
91570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91588d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
9159d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
91600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
91610b206f5daa453dc1035db5890cabc899736dc2d0glennrp
91620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
91630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
9164fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
9165fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
9166fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
91675a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
91685a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
91695a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
9170fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
91715a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
91725a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
9173fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
9174fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
9175fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9176fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
9177fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
9178fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9179fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
9180fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
9181fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
918216ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
9183fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
9184fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9185fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
9186fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
9187fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
9188fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
918916ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
9190fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
9191fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9192fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
9193fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
919416ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
919516ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
919616ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
919716ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
919816ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
919916ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
920016ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
9201fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
9202fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
9203fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
9204fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
9205fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
920616ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
9207fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
9208bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9209fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
9210fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
9211fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
9212fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9213fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
9214fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
921567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
921667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
921767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
9218fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
921967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
922067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
922167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
922267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
9223fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
922467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
922567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
9226fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
9227fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9228bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9229fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
9230fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
9231fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
9232fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9233fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
9234fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9235fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
9236fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9237fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
9238fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9239fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
9240fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
9241fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
9242fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
92433c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
92443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
92453c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
92463c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
9247f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
9248b0a657e13c4aefba39c51292005427b47277869dcristy  image_matte=image->alpha_trait == BlendPixelTrait ? MagickTrue : MagickFalse;
924983c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
92500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
92511273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
925352a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
925452a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
925552a479ca718756af72f96e127f8256499ab68f76glennrp    {
925616ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
925716ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
925816ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
925915e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
926016ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
926152a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
926252a479ca718756af72f96e127f8256499ab68f76glennrp    }
926352a479ca718756af72f96e127f8256499ab68f76glennrp
92643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
926816ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
926916ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
927016ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
9271cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
9272cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
92730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
927516ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
9276cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
92770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
92810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
92830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
92873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
9291cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
92923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
92963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
92993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
9303edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
9304cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9306edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9307edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (ping_pixels != (unsigned char *) NULL)
9308edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
9309edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9310edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (quantum_info != (QuantumInfo *) NULL)
9311edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        quantum_info=DestroyQuantumInfo(quantum_info);
9312edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
931316ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
931416ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
931516ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
931616ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9319edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9320edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
9321edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
9322edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
9323edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
9324edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9325edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
9326edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
9327edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
9328edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9329a3a5f956194e91458e2789966ad15308e8f3df47glennrp#if PNG_LIBPNG_VER >= 10400
9330a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
9331a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
9332a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
9333a3a5f956194e91458e2789966ad15308e8f3df47glennrp
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93379bf97b6c2143eb20c330346b01e82102cc082725glennrp
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
934025024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  {
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
934225024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
934325024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     /* Disable new libpng-1.5.10 feature when writing a MNG because
934425024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      * zero-length PLTE is OK
934525024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      */
934625024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     png_set_check_for_invalid_index (ping, 0);
934725024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# endif
934825024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  }
93492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
93542b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
93592b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93604e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
93614e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
93622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
93650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9366fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48 || mng_info->write_png64)
9367fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     image_depth=16;
9368fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
93710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
93750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
93780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
93810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9385e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9387e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93898a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        "    image_matte=%.20g",(double) image->alpha_trait);
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93918640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93938640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93958640fb5e9b1094f35f8beab436f81661b8a99448glennrp
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
93975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
9398dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
939926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
940126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
940226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
940316ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
9407dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9408dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9412dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
9413823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
941416ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
9415823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
941616ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9418dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9421dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
942216ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
942316ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9425991d11dd9c33e65872778b81aff1347cd2878154glennrp
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9428dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
942916ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
943016ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9432991d11dd9c33e65872778b81aff1347cd2878154glennrp
9433823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9434823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9435823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9436823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9437823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9438991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
944026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9442a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
944326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
944426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9445a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9447a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9448a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9449a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9450a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9451a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9452a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
94530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9454a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9455a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
94560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9457a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9458a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
94590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9460a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9461a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
94620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9463a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9464a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
94650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9466a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9467a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
94680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9469a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9470a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9471c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9472c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
94730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
94740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
94763b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
94773b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94783b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9479c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9480c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9481c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
94823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
94833b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94843b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
94853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
94860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
948826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
94950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94961273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9499fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
95000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
95010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
95038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
95048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
95050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
95070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
95080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
95090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
95100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
95120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9514f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
95150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
95170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
95180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
95190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
95200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
95210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
95220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
952367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
95240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
952567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
952667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
952767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
95280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
95312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
95338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
95348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
95355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
953658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
95378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
95380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
95390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
95400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
95410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
95428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
95458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
95460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95482cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
95498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
95500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
95520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
95530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
95558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
95568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
95570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95581273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
95594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
95601273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
95611273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
95621273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
95631273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
95644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
95654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
95664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
95670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9569c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9570c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9571c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9572c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9573c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9574c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9575c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
95764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
95773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
95780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9579fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png_colortype == 1)
9580fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
9581fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image_matte=MagickFalse;
9582fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
9583fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
9584fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
9585fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png24 || mng_info->write_png48 ||
9586fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 3)
95873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
95895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
95903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9592fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png32 || mng_info->write_png64 ||
9593fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 7)
95943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
95965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
95973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
96020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
96043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
96060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
96085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
96093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
96102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
96137c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
96147c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
96157c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96167c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96197c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
96203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
96223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96233c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
96240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9625d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
96268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
96270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9628d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9634d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96405aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
96415aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
96425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
96435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
96447c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
96457c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
96467c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96485aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
96498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
96505aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
96515aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96525aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
96535aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
96545aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96560b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
96575aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96585aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
96595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
96605aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
96625aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
96635aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
96645aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
96655aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96665aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96675aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
96685aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
96700b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
96715aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96725aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
96735aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
96745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
96760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
96775aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
968126c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96828640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
968326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
96845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
96850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
96860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
96870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
96880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
96890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
96900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9692d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9693d6bf1617e99df0272b231855a933a74e99b6578fglennrp
96945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
96953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96968a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (image->alpha_trait != BlendPixelTrait && ping_have_non_bw == MagickFalse)
96978d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
96983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96998640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
97013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
970235ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
97035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
97040f111984738842d27d04aed2a3f823d82a943506glennrp
97050f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
97060f111984738842d27d04aed2a3f823d82a943506glennrp           {
97070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9708edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"image has 0 colors");
97090f111984738842d27d04aed2a3f823d82a943506glennrp           }
97100f111984738842d27d04aed2a3f823d82a943506glennrp
971135ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
97125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9713d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
97143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9715d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9716d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9717d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9718d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
97190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9720d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9721d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9722d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
97230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9724d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9725d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
97263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
97292b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97331a56e9c9268976936eeab9fe97eb664b847e444cglennrp        "    Tentative PNG color type: %s (%.20g)",
97341a56e9c9268976936eeab9fe97eb664b847e444cglennrp        PngColorTypeToString(ping_color_type),
97351a56e9c9268976936eeab9fe97eb664b847e444cglennrp        (double) ping_color_type);
97360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9738e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
97390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9741e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
97420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
97458640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
97468640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97478640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9748e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
975158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
97544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
97557c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
97567c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
97577c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
97582b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97597c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
97607c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
97617c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
97622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
97644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
97664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
97674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
97684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
97694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
97704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9771a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
97724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
97737c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
97747c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
97757c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
97764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
97770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
97794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
97804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9781bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
97823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
97840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
97864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
97870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
97894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
97900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
97924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
97930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
97954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
97960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
97984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
97990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
98014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
98020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
98044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
98050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
980716ea139d53d867211d3bb0fa859a83de653f687ecristy                (ScaleQuantumToShort(GetPixelInfoIntensity(
98084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
98090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
98110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
98134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9818fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9819fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9820fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9821fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9822fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
98234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98242b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98277c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98287c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
98290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
98314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
98324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
98334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
98344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
98354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
98364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
98374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
98394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
98404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
98435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
98445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
98455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
98465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
98473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98508640fb5e9b1094f35f8beab436f81661b8a99448glennrp
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
98520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98532e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
98550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
985639992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
98588d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
98598d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
986135ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
98620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
98649c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
98650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98667c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
98685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
98694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
98714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
98724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
98734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
98744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
98764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
98774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
98784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
98793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
98800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
98830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9884136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9885d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9886f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
98870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
98895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
98900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
98935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
98945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
98953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
98963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
98985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
98990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
990035ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9901bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
99025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99052b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
99070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
99093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
99111a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
99123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
99284bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
99312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
99339c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
99340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
99369c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
99370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
99399c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
99403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99422b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
99450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
99470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
995017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
995117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
99553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
99575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
99580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99593d627862fb79aad8a20be4f1587f0b8761db441aglennrp            if (!(mng_info->have_write_global_plte && matte == MagickFalse))
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9961bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
99633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
99670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99683b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
997098156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
9971f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
99720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
997339992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
9977d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9979befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
9980befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
9981befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
99825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
9983befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
99840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
998516ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
99865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
99900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
999158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
99920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
99930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
9994d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
9995d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
99960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9998d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
9999d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
100020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
100030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10004d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
100050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
10006c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
10007c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
10008c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10009c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
10010c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
10011d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
10012d6bf1617e99df0272b231855a933a74e99b6578fglennrp
10013d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
10014d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
10015750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp                       ping_trans_alpha[i]= (png_byte)
1001616ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
10017d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
100180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
100190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
100203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10025c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
100263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
100280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
100303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
100314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
100354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
100415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
100425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
100435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
100444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
100494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100564383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
100574383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
100582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
100625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1006835ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
1006935ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
1007035ef824baa82511126ff0072ae30eee0da9c05a3cristy
1007122ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
100723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
1007426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
100753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1007616ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
1007716ea139d53d867211d3bb0fa859a83de653f687ecristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(
1007816ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
1007916ea139d53d867211d3bb0fa859a83de653f687ecristy
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
100818f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1008216ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
1008316ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1008416ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
1008516ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
100863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
10087991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
1008826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100903e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
100913e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100923e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
100933e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
100943e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
100959be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
100963e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
100973e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
100983e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
100993e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101003e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
101013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1010217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1010326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1010426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
101051273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
1010617a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
1010717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
1010817a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
1010917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
1011017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1011117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
1011217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10113a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
10114a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
1011517a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
1011617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1011717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
1011817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101193b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
101200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
101210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
101230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
10124a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1012513d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
10126a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
101270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
101283b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
101293b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
101310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
101330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
101340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
101350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
101360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
10137a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
1013817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10139d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
101403c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
101413b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101423b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101433b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
101443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
101453c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
1014617a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
1014726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1014817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101511a56e9c9268976936eeab9fe97eb664b847e444cglennrp      "    PNG color type: %s (%d)", PngColorTypeToString(ping_color_type),
101521a56e9c9268976936eeab9fe97eb664b847e444cglennrp      ping_color_type);
101533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
101543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
101553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
101580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
101600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
101630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
101640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
101660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
101700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101714054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
101724054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
1017310d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
1017410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1017510d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
1017610d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
1017710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1017810d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
1017910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1018010d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0: Use Z_HUFFMAN_ONLY strategy with the
1018110d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
1018210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1018310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
1018410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1018510d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
1018610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1018710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
1018810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1018910d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
1019010d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
1019110d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
10192750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
1019310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
1019410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1019510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
1019610d739ef54404090a55cb8977fc51f85cafa81a5glennrp             a MNG, othewise "none".  Did not work in IM-6.7.0-9
1019710d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
1019810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1019910d739ef54404090a55cb8977fc51f85cafa81a5glennrp        8:   Z_RLE strategy, all filters
102001868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
1020110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1020210d739ef54404090a55cb8977fc51f85cafa81a5glennrp        9:   Z_RLE strategy, no PNG filters
102031868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
1020410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1020510d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
1020610d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
1020716ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
1020816ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
1020910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1021010d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
1021110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
102140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102151868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
102161868258559ddf946fa73ef72dd43507b32623705glennrp    {
102171868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
102181868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
102191868258559ddf946fa73ef72dd43507b32623705glennrp    }
10220750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
102211868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
102223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
102243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
102253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10226bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
102270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102281868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
102291868258559ddf946fa73ef72dd43507b32623705glennrp    }
102300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102311868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
102321868258559ddf946fa73ef72dd43507b32623705glennrp    {
102331868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
10234a24b245fac14ef0617d691de0942697f2eb31b05glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
10235a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy=Z_RLE+1;
10236a24b245fac14ef0617d691de0942697f2eb31b05glennrp#else
10237a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
10238a24b245fac14ef0617d691de0942697f2eb31b05glennrp#endif
102393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102411868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
102421868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
102431868258559ddf946fa73ef72dd43507b32623705glennrp
102441868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
102453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102461868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
102473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102481868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
102491868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
102500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102511868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
102521868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102531868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
102541868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
102550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102561868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102571868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
102583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102594054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
1026010d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102611868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
102624054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
102634054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
102641868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102651868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
102661868258559ddf946fa73ef72dd43507b32623705glennrp        else
102671868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102681868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
102691868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
102703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102721868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
102731868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
102740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102751868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
102761868258559ddf946fa73ef72dd43507b32623705glennrp    {
102771868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
102781868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
102791868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
102801868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
102811868258559ddf946fa73ef72dd43507b32623705glennrp      else
102821868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
102831868258559ddf946fa73ef72dd43507b32623705glennrp     }
102844054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
102851868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
102861868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
1028710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
102881868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
102891868258559ddf946fa73ef72dd43507b32623705glennrp    {
102901868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
102911868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
102921868258559ddf946fa73ef72dd43507b32623705glennrp      {
102931868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
102941868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
102951868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
102961868258559ddf946fa73ef72dd43507b32623705glennrp      }
102971868258559ddf946fa73ef72dd43507b32623705glennrp#endif
102984054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
102991868258559ddf946fa73ef72dd43507b32623705glennrp    }
103000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103011868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
103021868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103041868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
103051868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
103061868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
103070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103081868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
103091868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
103101868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
103112b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10312dec72c9b492c176af9813be3105518e91835ed37glennrp  ping_interlace_method=image_info->interlace != NoInterlace;
10313dec72c9b492c176af9813be3105518e91835ed37glennrp
10314dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_mng)
10315dec72c9b492c176af9813be3105518e91835ed37glennrp    png_set_sig_bytes(ping,8);
10316dec72c9b492c176af9813be3105518e91835ed37glennrp
10317dec72c9b492c176af9813be3105518e91835ed37glennrp  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
10318dec72c9b492c176af9813be3105518e91835ed37glennrp
10319dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_png_colortype != 0)
10320dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10321dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
10322dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10323dec72c9b492c176af9813be3105518e91835ed37glennrp         {
10324dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
10325dec72c9b492c176af9813be3105518e91835ed37glennrp
10326dec72c9b492c176af9813be3105518e91835ed37glennrp           if (ping_bit_depth < 8)
10327dec72c9b492c176af9813be3105518e91835ed37glennrp             ping_bit_depth=8;
10328dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10329dec72c9b492c176af9813be3105518e91835ed37glennrp
10330dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
10331dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10332dec72c9b492c176af9813be3105518e91835ed37glennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
10333dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10334dec72c9b492c176af9813be3105518e91835ed37glennrp
10335dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_need_colortype_warning != MagickFalse ||
10336dec72c9b492c176af9813be3105518e91835ed37glennrp     ((mng_info->write_png_depth &&
10337dec72c9b492c176af9813be3105518e91835ed37glennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
10338dec72c9b492c176af9813be3105518e91835ed37glennrp     (mng_info->write_png_colortype &&
10339dec72c9b492c176af9813be3105518e91835ed37glennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10340dec72c9b492c176af9813be3105518e91835ed37glennrp      mng_info->write_png_colortype != 7 &&
10341dec72c9b492c176af9813be3105518e91835ed37glennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
10342dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10343dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10344dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10345dec72c9b492c176af9813be3105518e91835ed37glennrp          if (ping_need_colortype_warning != MagickFalse)
10346dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10347dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10348dec72c9b492c176af9813be3105518e91835ed37glennrp                 "  Image has transparency but tRNS chunk was excluded");
10349dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10350dec72c9b492c176af9813be3105518e91835ed37glennrp
10351dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_depth)
10352dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10353dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10354dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:bit-depth=%u, Computed depth=%u",
10355dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_depth,
10356dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_bit_depth);
10357dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10358dec72c9b492c176af9813be3105518e91835ed37glennrp
10359dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_colortype)
10360dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10361dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10362dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:color-type=%u, Computed color type=%u",
10363dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_colortype-1,
10364dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_color_type);
10365dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10366dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10367dec72c9b492c176af9813be3105518e91835ed37glennrp
10368dec72c9b492c176af9813be3105518e91835ed37glennrp      png_warning(ping,
10369dec72c9b492c176af9813be3105518e91835ed37glennrp        "Cannot write image with defined png:bit-depth or png:color-type.");
10370dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10371dec72c9b492c176af9813be3105518e91835ed37glennrp
10372dec72c9b492c176af9813be3105518e91835ed37glennrp  if (image_matte != MagickFalse && image->alpha_trait != BlendPixelTrait)
10373dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10374dec72c9b492c176af9813be3105518e91835ed37glennrp      /* Add an opaque matte channel */
10375dec72c9b492c176af9813be3105518e91835ed37glennrp      image->alpha_trait = BlendPixelTrait;
10376dec72c9b492c176af9813be3105518e91835ed37glennrp      (void) SetImageAlpha(image,OpaqueAlpha,exception);
10377dec72c9b492c176af9813be3105518e91835ed37glennrp
10378dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10379dec72c9b492c176af9813be3105518e91835ed37glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10380dec72c9b492c176af9813be3105518e91835ed37glennrp          "  Added an opaque matte channel");
10381dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10382dec72c9b492c176af9813be3105518e91835ed37glennrp
10383dec72c9b492c176af9813be3105518e91835ed37glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10384dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10385dec72c9b492c176af9813be3105518e91835ed37glennrp      if (ping_color_type < 4)
10386dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10387dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_have_tRNS=MagickTrue;
10388dec72c9b492c176af9813be3105518e91835ed37glennrp           if (logging != MagickFalse)
10389dec72c9b492c176af9813be3105518e91835ed37glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10390dec72c9b492c176af9813be3105518e91835ed37glennrp               "  Setting ping_have_tRNS=MagickTrue.");
10391dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10392dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10393dec72c9b492c176af9813be3105518e91835ed37glennrp
10394dec72c9b492c176af9813be3105518e91835ed37glennrp  if (logging != MagickFalse)
10395dec72c9b492c176af9813be3105518e91835ed37glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10396dec72c9b492c176af9813be3105518e91835ed37glennrp      "  Writing PNG header chunks");
10397dec72c9b492c176af9813be3105518e91835ed37glennrp
10398dec72c9b492c176af9813be3105518e91835ed37glennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
10399dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_bit_depth,ping_color_type,
10400dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_interlace_method,ping_compression_method,
10401dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_filter_method);
10402dec72c9b492c176af9813be3105518e91835ed37glennrp
10403dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
10404dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10405dec72c9b492c176af9813be3105518e91835ed37glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
10406dec72c9b492c176af9813be3105518e91835ed37glennrp
10407dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10408dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10409dec72c9b492c176af9813be3105518e91835ed37glennrp          for (i=0; i< (ssize_t) number_colors; i++)
10410dec72c9b492c176af9813be3105518e91835ed37glennrp          {
10411dec72c9b492c176af9813be3105518e91835ed37glennrp            if (i < ping_num_trans)
10412dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10413dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10414dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10415dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10416dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10417dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue,
10418dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10419dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) ping_trans_alpha[i]);
10420dec72c9b492c176af9813be3105518e91835ed37glennrp             else
10421dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10422dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d)",
10423dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10424dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10425dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10426dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue);
10427dec72c9b492c176af9813be3105518e91835ed37glennrp           }
10428dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10429dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10430dec72c9b492c176af9813be3105518e91835ed37glennrp
104310d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
104320d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
104333d627862fb79aad8a20be4f1587f0b8761db441aglennrp     (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
104340d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
104350d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
104360d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
104370d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
10438c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
10439c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
10440c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
104413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10442c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
104430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10444c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
10445c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
10446c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
10447c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
10448c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
1044926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
10450c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
10451c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
10452c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
1045316ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
10454e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
10455c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
10456e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
10457e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
10458e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
10459c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
10460918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                       ping_have_iCCP = MagickTrue;
10461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
1046226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
104630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10464c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
104653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10466c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
10467c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
10468cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
10469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
10470c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
10471c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
10472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
10473c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
104740b206f5daa453dc1035db5890cabc899736dc2d0glennrp
10475c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
10476c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10477c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
104780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10479c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
10480c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
104810d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
104823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
104833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
104853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
104863d627862fb79aad8a20be4f1587f0b8761db441aglennrp      (png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
104873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1048826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
1048926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1049026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
1049126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
1049226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
1049326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
1049426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1049526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
104960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1049726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
10498cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
10499cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
10500918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp
10501918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB = MagickTrue;
1050226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
105033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1050426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
105055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105082cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
10509918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_iCCP == MagickFalse &&
10510918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB == MagickFalse &&
105112cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
1051226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
1051326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
105143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
105153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
105183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
105193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
105203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
105233b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
105243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1052626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
105272b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10528918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp      if (ping_exclude_cHRM == MagickFalse && ping_have_sRGB == MagickFalse)
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1053026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
1053126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
1053226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
1053326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
1053426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
10535918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                Note: if cHRM+gAMA == sRGB write sRGB instead.
1053626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
1053726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
1053826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
1053926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
1054026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
1054126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
1054226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1054326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1054426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1054526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1054626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1054726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1054826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1054926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1055026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1055126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1055226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1055326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1055426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1055526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
105563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10557dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1055826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1055926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1056026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10561c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1056226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
10563c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging)
10564c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10565c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10566c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10567c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10568c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10569c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10570c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10571c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10572c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10573c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10574c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10575c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10576c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10577c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1057826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10579991d11dd9c33e65872778b81aff1347cd2878154glennrp
1058026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10581dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1058226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1058326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1058426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1058526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1058626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1058726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10588823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
10589823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
10590823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10591823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10592823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10593823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10594823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10595823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10596823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10597823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10598823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10599823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10600823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10601823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10602823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1060326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10604dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10605dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10606dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
106074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10608dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1060926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1061026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1061126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1061226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10613dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1061426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1061526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1061626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1061726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1061826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10619dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10620dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10621dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10622da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10623da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1062416ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10625da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10626da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10627da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10628da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10629da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10630da8f3a7bfddac2680a3069a490db541e7944edafglennrp
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10632991d11dd9c33e65872778b81aff1347cd2878154glennrp
1063339992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10634991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
106353b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
106360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
106370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
106390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10640991d11dd9c33e65872778b81aff1347cd2878154glennrp
106410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
106420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
106430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
106440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
106450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10646991d11dd9c33e65872778b81aff1347cd2878154glennrp
106470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
106480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
106490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
106500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
106510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
106520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
106530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
106550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
106560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10657c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
106580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
106590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
106600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
106610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
106620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
106630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10664991d11dd9c33e65872778b81aff1347cd2878154glennrp
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10666cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10667da8f3a7bfddac2680a3069a490db541e7944edafglennrp
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10669991d11dd9c33e65872778b81aff1347cd2878154glennrp
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10671cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1067326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
106764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1067726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1067826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1067926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1068026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1068126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1068226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1068303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1068426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1068526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1068626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1068726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1068826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1068926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
106939c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
106959c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10704b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10705b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
107067202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10708b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10710b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10712b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10713b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10714b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10716b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10718b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10720b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10721b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107233b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
107243b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10726b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10727b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
107280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10729b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10730e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10732cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
10733cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
107340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10735cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
10736edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Allocation of memory for pixels failed");
107370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10741ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10742ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10743edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation for quantum_info failed");
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
107464b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
107488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10750fd164d2bf84b111e304959af5698757d60e9b8aeglennrp       !mng_info->write_png48 && !mng_info->write_png64 &&
107518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
107528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
107548d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
107558d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1075816ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
107600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
107623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10769d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
107703b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107713b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10772a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1077316ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
107740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1077516ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
107770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1078016ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1078116ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
107833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
107843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10787bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10788cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
107893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
107920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1079516ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1079616ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
107980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10800bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10801cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
108030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108043b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10805b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10806b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
108070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10808cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10822fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png48 && !mng_info->write_png64 &&
10823fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png32) && (image_matte != MagickFalse ||
10824fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
10825fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (mng_info->IsPalette) && ping_have_color == MagickFalse)
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1082716ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
108288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
108290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
108328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10833bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1083516ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
108362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1083716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
108392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
108405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
108428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1084316ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1084416ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
108452cc891a179d622dde7bbb8854138851e828bc6eaglennrp
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1084716ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1084816ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
108492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
108508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
108518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
108542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
108558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10856b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
108573b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10858b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
108602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1086116ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1086216ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
10863b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
108642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
108653b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10866b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
108682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10869cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
108712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
108728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
108738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
108748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
108758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
108768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
108778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
108788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
108798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
108800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1088316ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
108848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
108850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10888fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            if ((image_depth > 8) ||
10889fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 ||
108908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
10891fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 ||
10892fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png64 ||
10893fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
108948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
108958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10896b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
10897862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
108982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1089916ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
109008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
109012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
109048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1090516ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1090616ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
109072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1090916ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1091016ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
109118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
109148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1091516ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10916cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1091716ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
109182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
109208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
109228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1092516ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1092616ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
109272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1092916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1093016ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
109312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109323b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10933b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
109352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10936cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
10937b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
109388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
109392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
10941fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            /* not ((image_depth > 8) ||
10942fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 || mng_info->write_png32 ||
10943fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 || mng_info->write_png64 ||
10944fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
10945fd164d2bf84b111e304959af5698757d60e9b8aeglennrp             */
109468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
109478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
109488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
109498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
109508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
109518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
109532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
109558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
109568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
109572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
109598640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
109608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
109618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
109632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1096416ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
109652cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1096616ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
109678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
109682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1097044757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
109714bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
109724bf89731a90c6e03598950223e19e7be7b95d630glennrp
1097316ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1097416ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1097544757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
109762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
109788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
109798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
109808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
109822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1098316ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10984cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1098516ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
109868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
109898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1099016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1099116ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
109922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109935eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
109945eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
109955eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109961a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
109975eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
109985eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109995eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
110005eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
110015eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
110028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
11003cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
110048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
110058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
110062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
110088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
110098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
110108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
110118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110128640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
110133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
110168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
11017b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
11018b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11023b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
110240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11026e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
110270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11029e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
110300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110345d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
110353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
110390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110435d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
110480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
110513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11053a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11055823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1105726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1105826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1105926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1106026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1106126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1106226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
110632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1106416ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
11065a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11066a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      /* Don't write any "png:" properties; those are just for "identify" */
11067a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(property,"png:",4) != 0 &&
11068a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11069a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
11070a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
11071823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
11072a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
11073a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11074a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
11075a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
11076a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1107726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
11078c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
11079c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
11080a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy
11081a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
11082a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,
11083a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy                 (png_alloc_size_t) sizeof(png_text));
11084a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
11085a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
11086a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
11087c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
11088c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
11089c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
110902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11091c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
11092c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
110932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11094c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
11095c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
110962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11097c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1109826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
11099c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
11100c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
11101c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
11102c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1110326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
111042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11105c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
11106c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
11107c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11108c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
11109c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11110c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11111cbc9215c23fce410bf0bea825dee908c15271bb3glennrp                  "    keyword: '%s'",text[0].key);
11112c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
11113c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11114c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
11115c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
11116c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1111726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1111826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1111926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
111213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
11123cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
111280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
111300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
111345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
111355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
111363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
111383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
111413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
111423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1114503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
111473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
111483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
111493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
111503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
111513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
111523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
111533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
111543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
111565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
111595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
111673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
111683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
111703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
11171edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
111720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
111783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11179cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
111803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1118116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1118216ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1118316ea139d53d867211d3bb0fa859a83de653f687ecristy
1118416ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1118516ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1118616ea139d53d867211d3bb0fa859a83de653f687ecristy
11187b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
11188b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
11189b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
11190b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1119116ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
11192b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
111960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11197edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
11198edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
11199edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
11200edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
11201edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   /* }  for navigation to beginning of SETJMP-protected block. Revert to
11202edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    *    Throwing an Exception when an error occurs.
11203edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    */
11204edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
11207edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1122816ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1122916ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1123716ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1123816ea139d53d867211d3bb0fa859a83de653f687ecristy%
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
112455d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112475a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
112485a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
112493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
112515a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
112525a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
11253e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
11254130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
11255130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
11256130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
11257e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
11258e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
11259e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
112605a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
112615a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
112623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
112635a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
112645a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
112655a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
112663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
112683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
112695a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
112705a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
112715a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
112725a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
112735a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
112763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
112773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
112780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
112795a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
112805a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11282fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG48:   A 16-bit per sample RGB PNG datastream is written.  The tRNS
11283fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               chunk can be present to convey binary transparency by naming
11284fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               one of the colors as transparent.  If the image has more
11285fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               than one transparent color, has semitransparent pixels, or
11286fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               has an opaque pixel with the same RGB components as the
11287fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparent color, an image is not written.
11288fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
11289fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG64:   A 16-bit per sample RGBA PNG is written.  Partial
11290fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparency is permitted, i.e., the alpha sample for
11291fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               each pixel can have any value from 0 to 65535. The alpha
11292fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               channel is present even if the image is fully opaque.
11293fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
112945830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%    o PNG00:   A PNG that inherits its colortype and bit-depth from the input
112955830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               image, if the input was a PNG, is written.  If these values
112965830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               cannot be found, then "PNG00" falls back to the regular "PNG"
112975830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               format.
112985830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
113013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
11302bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
11303bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
11304bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
113093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
113133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
113163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
113183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
113203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11322fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               If the image cannot be written without loss with the
11323fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               requested bit-depth and color-type, a PNG file will not
11324fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               be written, a warning will be issued, and the encoder will
11325fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               return MagickFalse.
113265a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
113273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
113283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
113293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
113305a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1133116ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
113323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
113343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
113353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
113363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
113383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
113393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
113403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
113413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
113433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
113453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
11346bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
11347bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
113503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
113513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
11352bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
113533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11354bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
113553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113563241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
113570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
11358d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
113590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
113600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
113610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
11362cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
113630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
11364d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
11365d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
113665d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
11367d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
11368d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
11369d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
11370d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
113710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
113723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
113743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1137516ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
113763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
113773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1137821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1137921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1138021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
113843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
113853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1139021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
113915c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
113925c7cf4e469a4dad7e277783749155932252c52dfglennrp
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
113953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11401fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
114043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1140673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
114070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
114093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
114100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
11416a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
114173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
114183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
114203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
11424fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png48=LocaleCompare(image_info->magick,"PNG48") == 0;
11425fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png64=LocaleCompare(image_info->magick,"PNG64") == 0;
114263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114278b206bac411969018dc3a6d395f525f1664af412cristy  value=GetImageArtifact(image,"png:format");
11428b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11429b381a2618e8bb9e1e76299676711d0ec1063feabglennrp  if (value != (char *) NULL)
11430b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
11431f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11432f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp         "  Format=%s",value);
11433f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11434fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png8 = MagickFalse;
11435fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png24 = MagickFalse;
11436fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png32 = MagickFalse;
11437fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png48 = MagickFalse;
11438fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png64 = MagickFalse;
11439fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11440b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
11441b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
11442b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11443b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11444b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11445b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11446b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11447b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11448fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11449fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png48") == 0)
11450fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png48 = MagickTrue;
11451fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11452fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png64") == 0)
11453fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png64 = MagickTrue;
114545830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
11455f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp      else if (LocaleCompare(value,"png00") == 0)
114565830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        {
11457f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          /* Retrieve png:IHDR.bit-depth-orig and png:IHDR.color-type-orig
11458f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp             Note that whitespace at the end of the property names must match
11459f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp             that in the corresponding SetImageProperty() calls.
11460f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp           */
11461f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          value=GetImageProperty(image,"png:IHDR.bit-depth-orig  ",exception);
11462f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11463f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11464f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11465f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11466f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited bit depth=%s",value);
11467f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11468f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"1") == 0)
11469f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 1;
11470f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11471f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"1") == 0)
11472f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 2;
11473f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11474f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"2") == 0)
11475f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 4;
11476f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11477f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"8") == 0)
11478f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 8;
11479f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11480f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"16") == 0)
11481f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 16;
11482f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
11483f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11484f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          value=GetImageProperty(image,"png:IHDR.color-type-orig ",exception);
11485f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11486f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11487f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11488f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11489f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited color type=%s",value);
11490f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11491f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"0") == 0)
11492f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 1;
11493f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11494f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"2") == 0)
11495f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 3;
11496f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11497f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"3") == 0)
11498f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 4;
11499f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11500f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"4") == 0)
11501f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 5;
11502f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11503f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"6") == 0)
11504f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 7;
11505f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
115065830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        }
115075830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
115085830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
115103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115119c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
115129c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115139c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
115173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115189c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
115199c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115209c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115228a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      if (image->alpha_trait == BlendPixelTrait)
1152316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
115240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115259c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1152616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
115270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1152816ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
115293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
115323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115339c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
115349c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115359c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115378a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      if (image->alpha_trait == BlendPixelTrait)
1153816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
115390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115409c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1154116ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
115420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1154316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
115443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11546fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48)
11547fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11548fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 2 */ 3;
11549fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11550fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
11551fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
115524dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      if (image->alpha_trait == BlendPixelTrait)
115534dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
11554fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11555fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else
115564dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorType,exception);
11557fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
115584dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11559fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11560fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11561fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png64)
11562fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11563fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 6 */  7;
11564fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11565fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
11566fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
115674dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      if (image->alpha_trait == BlendPixelTrait)
115684dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
11569fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11570fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else
115714dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorType,exception);
11572fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
115734dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11574fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11575fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
115768b206bac411969018dc3a6d395f525f1664af412cristy  value=GetImageArtifact(image,"png:bit-depth");
115778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
115783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
115793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
115819c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
115820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
115849c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
115850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
115879c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
115880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
115909c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
115910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
115939c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
115940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11595bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1159616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11597bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11598bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11599bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11600bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
116013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
116029c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11603bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
116043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116068b206bac411969018dc3a6d395f525f1664af412cristy  value=GetImageArtifact(image,"png:color-type");
116070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
116113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
116129c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
116130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1161416ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1161516ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1161616ea139d53d867211d3bb0fa859a83de653f687ecristy
116173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116189c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
116190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
116219c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
116220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
116249c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
116250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
116279c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
116280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11629bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1163016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11631bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11632bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11633bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11634bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
116353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
116369c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11637d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
116383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
116410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116420dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
116430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
116440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116455d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
116460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
116470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
116480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
116490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
116500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
116520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116535d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
116545d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
116550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
116560dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
116570dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
116580dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11659aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11660aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11661aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
116620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
116640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
116650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
116660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
116680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
116690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
116700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
116720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
116730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116740e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11675104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
116760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
116770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1167826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1167926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11680a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1168126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1168226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1168326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1168426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1168526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1168626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1168726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1168826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11689a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1169026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1169126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1169226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1169326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
116948d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
116958d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
116968d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  value=GetImageArtifact(image,"png:preserve-colormap");
116978d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
116988b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:preserve-colormap");
116998d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
117008d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
117018d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
117021868258559ddf946fa73ef72dd43507b32623705glennrp  /* Thes compression-level, compression-strategy, and compression-filter
117031868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
117041868258559ddf946fa73ef72dd43507b32623705glennrp   */
117051868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-level");
117061868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
117078b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-level");
117081868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
117091868258559ddf946fa73ef72dd43507b32623705glennrp  {
117101868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
117111868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
117121868258559ddf946fa73ef72dd43507b32623705glennrp       */
117131868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
117141868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
117151868258559ddf946fa73ef72dd43507b32623705glennrp
117160ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
117171868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
117181868258559ddf946fa73ef72dd43507b32623705glennrp
117191868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
117201868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
117211868258559ddf946fa73ef72dd43507b32623705glennrp
117221868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
117231868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
117241868258559ddf946fa73ef72dd43507b32623705glennrp
117251868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
117261868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
117271868258559ddf946fa73ef72dd43507b32623705glennrp
117281868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
117291868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
117301868258559ddf946fa73ef72dd43507b32623705glennrp
117311868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
117321868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
117331868258559ddf946fa73ef72dd43507b32623705glennrp
117341868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
117351868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
117361868258559ddf946fa73ef72dd43507b32623705glennrp
117371868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
117381868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
117391868258559ddf946fa73ef72dd43507b32623705glennrp
117401868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
117411868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
117421868258559ddf946fa73ef72dd43507b32623705glennrp
117431868258559ddf946fa73ef72dd43507b32623705glennrp      else
1174416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
117451868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
117461868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
117471868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
117481868258559ddf946fa73ef72dd43507b32623705glennrp    }
117491868258559ddf946fa73ef72dd43507b32623705glennrp
117501868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-strategy");
117511868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
117528b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-strategy");
117531868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
117541868258559ddf946fa73ef72dd43507b32623705glennrp  {
117551868258559ddf946fa73ef72dd43507b32623705glennrp
117561868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
117571868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
117581868258559ddf946fa73ef72dd43507b32623705glennrp
117591868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
117601868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
117611868258559ddf946fa73ef72dd43507b32623705glennrp
117621868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
117631868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
117641868258559ddf946fa73ef72dd43507b32623705glennrp
117651868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1176698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
117671868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1176898c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1176998c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1177098c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
117711868258559ddf946fa73ef72dd43507b32623705glennrp
117721868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1177398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
117741868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1177598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1177698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1177798c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
117781868258559ddf946fa73ef72dd43507b32623705glennrp
117791868258559ddf946fa73ef72dd43507b32623705glennrp      else
1178016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
117811868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
117821868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
117831868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
117841868258559ddf946fa73ef72dd43507b32623705glennrp    }
117851868258559ddf946fa73ef72dd43507b32623705glennrp
117861868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-filter");
117871868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
117888b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-filter");
117891868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
117901868258559ddf946fa73ef72dd43507b32623705glennrp  {
117911868258559ddf946fa73ef72dd43507b32623705glennrp
117921868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
117931868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
117941868258559ddf946fa73ef72dd43507b32623705glennrp       *
117951868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
117961868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
117971868258559ddf946fa73ef72dd43507b32623705glennrp       */
117981868258559ddf946fa73ef72dd43507b32623705glennrp
117991868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118001868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
118011868258559ddf946fa73ef72dd43507b32623705glennrp
11802b19b8125320afb5954bd73b82d00700e8ed9e984cristy      else if (LocaleCompare(value,"1") == 0)
118031868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
118041868258559ddf946fa73ef72dd43507b32623705glennrp
118051868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118061868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
118071868258559ddf946fa73ef72dd43507b32623705glennrp
118081868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118091868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
118101868258559ddf946fa73ef72dd43507b32623705glennrp
118111868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118121868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
118131868258559ddf946fa73ef72dd43507b32623705glennrp
118141868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118151868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
118161868258559ddf946fa73ef72dd43507b32623705glennrp
118171868258559ddf946fa73ef72dd43507b32623705glennrp      else
1181816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118191868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118201868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
118211868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118221868258559ddf946fa73ef72dd43507b32623705glennrp    }
118231868258559ddf946fa73ef72dd43507b32623705glennrp
1182403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1182503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
118265c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
118275c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
118285c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11829acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
118305c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
11831acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11832acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11833acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
11834acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
118355c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11836acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
118378b206bac411969018dc3a6d395f525f1664af412cristy       value=GetImageArtifact(image,"png:exclude-chunk");
1183826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11839acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
118408b206bac411969018dc3a6d395f525f1664af412cristy         value=GetImageArtifact(image,"png:exclude-chunks");
11841acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11842acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1184303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1184403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1184526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1184603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1184703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1184826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1184903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1185026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1185103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
118522cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
118532cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
118542cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118552cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
118562cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
118572cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118582cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
118592cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1186003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1186103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1186203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1186303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1186403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1186503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1186603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1186703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1186803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1186903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
11870a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
1187103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1187203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1187303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1187403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1187503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1187603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1187703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1187803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
11879a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1188003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1188103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1188203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1188303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1188403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
118852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1188603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1188703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1188803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1188903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
11890a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
1189103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1189203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1189303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1189403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1189503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1189603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1189703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1189803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
11899a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1190003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1190103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1190203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1190303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
119042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1190503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1190603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
119072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1190803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1190903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
119102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11911a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11912a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
11913a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1191403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1191503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
119162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1191703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1191803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
119192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1192003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1192103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
119222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1192303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1192403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1192503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1192603812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
119272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1192803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1192903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
119302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1193103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1193203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
119332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1193403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1193503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
119362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11937a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11938a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
119392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1194003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1194103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
119422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11943a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11944a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
11945a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1194603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1194703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
119482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1194903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1195003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
119512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1195203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1195303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
119542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1195503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11956ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1195726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1195826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
119595c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
119605c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
119615c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11962acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
119635c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
11964acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11965acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11966acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
11967acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
119685c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11969acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
119708b206bac411969018dc3a6d395f525f1664af412cristy       value=GetImageArtifact(image,"png:include-chunk");
1197126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11972acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
119738b206bac411969018dc3a6d395f525f1664af412cristy         value=GetImageArtifact(image,"png:include-chunks");
11974acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11975acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1197603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1197703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1197803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1197903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1198026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1198103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1198226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1198303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
119842cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
119852cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
119862cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119872cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
119882cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
119892cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119902cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
119912cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1199203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1199303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1199403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1199503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1199603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1199703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1199803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1199903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1200003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
12001a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickFalse;
1200203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1200303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1200403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1200503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1200603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1200703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1200803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1200903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
12010a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1201103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1201203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1201303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1201403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1201503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
120162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1201703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1201803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1201903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1202003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
12021a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickTrue;
1202203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1202303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1202403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1202503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1202603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1202703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1202803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1202903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
12030a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1203103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1203203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1203303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1203403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
120352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1203603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1203703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
120382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1203903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1204003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
120412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12042a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
12043a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
12044a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1204503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1204603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
120472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1204803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1204903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
120502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1205103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1205203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
120532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1205403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1205503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1205603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1205703812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
120582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1205903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1206003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
120612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1206203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1206303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
120642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1206503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1206603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
120672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12068a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
12069a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
120702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1207103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1207203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
120732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12074a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
12075a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
12076a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1207703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1207803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
120792cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1208003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1208103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
120822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1208303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1208403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
120852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1208603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
12087ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1208826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1208926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1209003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1209126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1209226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120935d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1209426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1209526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1209726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1209826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
12100a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
12101a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12102a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1210326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1210426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1210526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1210626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1210726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1210826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1210926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1211026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1211226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1211326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1211426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1211626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1211726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1211826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1212026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1212126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1212226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1212326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1212426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1212526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1212626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1212726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1212826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
12129a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
12130a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12131a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1213226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1213326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1213426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1213526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1213626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1213726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1213826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1213926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1214026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1214126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1214226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
12143b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
121443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1214516ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
121463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
121480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
121510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
121533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
121543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
121563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
121583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1215916ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
121603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
121613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
121623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
121633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
121653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
121663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1216803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
121693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
121703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
121723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
121733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
121753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
121763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
121773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
121783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
121803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
121813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
121823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
121833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
121843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12185bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1218659575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
121873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
121883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
12190fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
121933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
121943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
121953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
121973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
121988a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     image_info->type==TrueColorMatteType || image->alpha_trait == BlendPixelTrait;
121993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1220059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1220159575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1220259575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1220359575fa5c228308a41d7f5028390be2083aaaf6dglennrp
12204750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1220559575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1220659575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1220759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1220859575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
122093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
122113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
122130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
122163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1221716ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
122180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
122200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
122223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
122253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
122270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1222816ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
122293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
122303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122328a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      jpeg_image->alpha_trait=UndefinedPixelTrait;
122338f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1223416ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1223516ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
122363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
122373b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy      (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
122383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
122393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1224059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1224159575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1224259575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1224359575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1224459575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1224559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
122463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
122483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
122503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
122517fb2652ba366fc984d1dbb0c66560b91c57dab78cristy    TrueColorType && IsImageGray(image,exception))
122523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
122533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1225459575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1225559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1225659575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1225759575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1225859575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1225959575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
1226059575fa5c228308a41d7f5028390be2083aaaf6dglennrp        if (transparent)
1226159575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1226259575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1226359575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1226459575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1226559575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1226659575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1226759575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1226859575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1226959575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1227059575fa5c228308a41d7f5028390be2083aaaf6dglennrp
122713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
122723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
122743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
122763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1227816ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1228016ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
122843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
122853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
122873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
122883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12290cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
12291cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
12292cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
122933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1229416ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1229716ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
122983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
122993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
123003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
123013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1230316ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
123043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1230616ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
123103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
123113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
123123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
123143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1231516ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
123163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
123170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
123193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12320e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
12321e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
123253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
123273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
123283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
123313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
123323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1233303812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
123344e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
123354e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
123363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
123373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
123393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
123403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
123413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
123423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
123433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
123443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
123453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
123463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
123483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12349f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
123500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12352f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
123530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
123560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
123590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
123620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
123650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
123680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
123710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
123740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
12380cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
123873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
123883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
123893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
123933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
123963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12397bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
123983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
123993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
124013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
12404bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
124053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1240603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
124083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
124093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
124103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
124113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
124123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
124133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
124143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
124153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
124163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
124173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
124193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
124213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
124263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1242703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
124280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
12430e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12431cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12432e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
124330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12435e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12436cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12437e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
124380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
124403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
124453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
124483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
124503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1245103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1245235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
124533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
124543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
124553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
124583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
124593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
124613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
124623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
124653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1246803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
124693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1247035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1247135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
124723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1247335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1247435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
124753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1247635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1247735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
124783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1247935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1248035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
124813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
124823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
124833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1248616ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
124873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
124903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
124923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1249303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
124943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
124953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1249635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1249716ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
124980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1249935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1250016ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
125010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
125033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
125083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1250935ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1251016ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
125110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1251235ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1251316ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
125140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
125163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1252016ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1252116ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
125223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
125303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
125323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1253603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12537bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12538bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
125393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
125403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
125443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
125463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1254703812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
125483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
125493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
125503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
125523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12560bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
125623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12563bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
125643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
125653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
125673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12569e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12570f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
125713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
125733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12575bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
125763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
125773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
125790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12583bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1258403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
125873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
125883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12594e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12595e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
125963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
125993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
126003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
126043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12605e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12606bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
126073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1260803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
126093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
126103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
126113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
126123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
126133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
126143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
126153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
126193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
126223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
126233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
126243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
126253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
126293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1263016ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
126313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
126323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
126333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
126343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
126363b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
126373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
126383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1264016ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12644e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12645e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
126463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
126483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
126490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1265059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1265159575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
126523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
126533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
126540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
126580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1265916ea139d53d867211d3bb0fa859a83de653f687ecristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,exception);
126600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12664e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12665e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12668e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12672bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1267403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
126753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
126773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
126783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
126803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
126833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12685cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
126883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
126893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1269003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
126933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
126970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
126993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
127003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
127143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
127163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
127183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1271916ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1272016ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
127213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1272816ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1272916ea139d53d867211d3bb0fa859a83de653f687ecristy%
127303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1273216ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1273316ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1273621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1273703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
127383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
127453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12751fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1275216ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
127533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
127543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
127583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1276073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
127613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
127623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
127693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1277216ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
127763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
127773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
127783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
127793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
127803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1278316ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1278416ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1279321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
127943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1279603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1279703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1279803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
128013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
128033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
128043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
128063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
128083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
128113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
128133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
128143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12816bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
128213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
128253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12826bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12829bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
128323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12833d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
128373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
128413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
128453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12847fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1284816ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1285673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
128573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
128633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
128743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
128753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
128763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
128793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
128803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
128813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
128833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
128843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
128853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
128873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
128883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
128903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
128913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
128923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
128933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
128970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12899e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
129000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
129033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
129053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
129063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12908e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
129090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12911e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
129120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12913dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy        if (p->alpha_trait == BlendPixelTrait)
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
129160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
129200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
129240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
129280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
129303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12931e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
129320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
129360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
129393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
129403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
129433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
129443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
129503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
129553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
129563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
129573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
129583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
129603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
129613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
129623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
129643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
129653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
129663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
129683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
129713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
129743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
129763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
129773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
129783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
129793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
129803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
129823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
129833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
129843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
129853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
129863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
129873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
129883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
129893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
129903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
129913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
129923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
129963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
129983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
129990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
130013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
130060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13007dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy        if (next_image->alpha_trait == BlendPixelTrait)
130083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
130090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
13011dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy          if ((next_image->alpha_trait == BlendPixelTrait) ||
13012dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy               next_image->page.x || next_image->page.y ||
130133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
130153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
130160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
130183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
130190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
130210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
130243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
130250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
130293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
130303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
130318a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        if (image->alpha_trait == BlendPixelTrait)
130323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
130330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
130353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130367fb2652ba366fc984d1dbb0c66560b91c57dab78cristy            if (IsImageGray(image,exception) == MagickFalse)
130373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
130383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
130393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
130403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
130413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
130423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
130453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
130473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
130483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
130493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
130503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
130513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
130530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
130560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
130583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
130600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1306216ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1306316ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
130650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
130673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
130703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
130723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
130733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
130743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
130753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
130763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
130773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
130783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
130793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
130803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
130813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
130823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
130833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
130843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
130853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
130863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
130883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
130893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
130903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
130913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
130923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
130933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
130943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
130953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
130963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
130973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
130983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
130993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
131003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
131013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
131023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
131030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
131073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
131083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
131103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
131113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
131133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
131143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
131153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
131163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
131170261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
13118d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
13119d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1312016ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1312116ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
13122d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
13123d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
13124d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
13130cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
13131cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
131333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
131340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
131363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
131370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
131393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
131400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
131423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
131433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
131463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
131493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
131503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
131533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
131543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
131573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
131593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
131603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1316103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
131624e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
131634e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
131643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
131653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
131663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
131673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
131683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
131693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
131740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
131773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
131830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
131863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
131903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
131950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
131983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
132013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
132033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
132040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
132073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
132103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
132118b206bac411969018dc3a6d395f525f1664af412cristy     option=GetImageArtifact(image,"mng:need-cacheoff");
132123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
132133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
132153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
132163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
132193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
132213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
13222bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1322303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
132243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
132253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
132263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
132273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
132293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
132303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
132313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
132343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
132363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1323703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
132383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
132393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
132403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
132413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
132420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
132443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
132450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
132473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
132480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
132503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13252e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
13253e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
132540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
132563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13257e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
132580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13261e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
132623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
132643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
132653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
132673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
132683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
132693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
132703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
132713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
132743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
132763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1327703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
132780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
13280e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13281cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13282e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
132830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
13285e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13286cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13287cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
132880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
132903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
132913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
132923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
132953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
132973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
133003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
133013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
133023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1330303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1330435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
133053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
133063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
133073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
133083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
133103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
133123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
133133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
133153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
133163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
133173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
133183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1331903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
133203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1332135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1332235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
133233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1332435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1332535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
133263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1332735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1332835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
133293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1333035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1333135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
133323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
133333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
133343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
133353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1333716ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
133383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
133413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
133433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1334403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
133450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
133473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1334835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1334916ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
133500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1335135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1335216ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
133530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
133553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
133583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
133603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1336135ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1336216ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
133630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1336435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1336516ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
133660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
133683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
133713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1337216ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1337316ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
133743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
133753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
133783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
133793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
133813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
133823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
133833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
13384dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy     if (write_mng && ((image->alpha_trait == BlendPixelTrait) ||
13385dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy         image->page.x > 0 || image->page.y > 0 || (image->page.width &&
133863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
133873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
133883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
133893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
133913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1339203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
133933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
133943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
133953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
133963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
133973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
133983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
133993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
134003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
134013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
134023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
134033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
134043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1340503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
134063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
134073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
134083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
134093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
134103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
134123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
134133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
134143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
134153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
13416bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
134173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
134183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
134203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
134213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
134223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
134233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
134243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1342503812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
134260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13427bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
134283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1342916ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1343016ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1343116ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1343216ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1343316ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1343416ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
134353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
134360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
134383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
134393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
134403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
134413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
134433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
134443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
134453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
134483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
134503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
134513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
134523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
134533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
134563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
134573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
134583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
134593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
134603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
134613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
134623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
134643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
134653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
134663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
134673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
134683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
134693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
134703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
134713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
134723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
134733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
13474bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
134753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
134763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
134783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
134793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1348003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
134810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13482bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
134833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
134843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
134853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
134863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
134873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
134880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
134903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
134913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
134923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
134933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
134943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
134973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
134983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
135003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
135023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
135033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
135043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
135063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
135073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
135083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
135093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
135113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
135123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
135133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
135143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
135163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
135173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
135183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
135193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
135203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1352103812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
135223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
135233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
135243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
135253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
135263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
135273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
135283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
135293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
135303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
135323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
135333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
135353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
135373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
135383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
135403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
135413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
135423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
135443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
135473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
135493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1355003812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
135513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
135533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
135543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
135563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
135593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
135613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1356203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
135633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
135653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
135663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
135673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
135683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
135693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
135703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
135713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
135723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
135733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
135744e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
135753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
135773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
135803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
135813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
135833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
135843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
135883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
135893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
135903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1359116ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
135923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
135933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
135953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
135963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
136002f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13601b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
136028d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
136032f2e514554975d510c88df54de98c6cdc1080f1cglennrp
136042f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
136052f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
136062f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13607a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
136082f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
136092f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
136102f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
136112f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
136122f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
136132f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
136142f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
136152f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13616a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
136172f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
136182f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
136192f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
136202f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1362116ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
136223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
136233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
136243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
136263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
136273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
136283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
136293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
136303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
136313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
136323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
136343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
136353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
136360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
136410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
136433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
136443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
136453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
136463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
136473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
136483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
136493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
136503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1365103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
136523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
136533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
136543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
136553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
136563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
136573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
136583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
136593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
136600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
136623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
136630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
136653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13666d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1366739992b4dd9b12ef752d55b8e402c069698851f72glennrp
136683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
136693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136703bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
136713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
136723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
136730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
136753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
136763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1367739992b4dd9b12ef752d55b8e402c069698851f72glennrp
136783ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
136793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
136813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13682d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
136833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13684