png.c revision 75fc68f33e6e766a22e8ed653c3ed50b0d142827
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   N   N   GGGG                              %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P   P  NN  N  G                                  %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   N N N  G  GG                              %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      N  NN  G   G                              %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      N   N   GGG                               %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%              Read/Write Portable Network Graphics Image Format              %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                John Cristy                                  %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                           Glenn Randers-Pehrson                             %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                               November 1997                                 %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
211454be7db7a897f42cd40e4165f945d77196a6f8cristy%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/studio.h"
4516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/artifact.h"
4616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/attribute.h"
4716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/blob.h"
4816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/blob-private.h"
4916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/cache.h"
50aa2c16cb5e695053aa78e40f66bc36fbef4b1ed1cristy#include "MagickCore/channel.h"
5116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/color.h"
5216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/color-private.h"
5316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colormap.h"
5416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colorspace.h"
5516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colorspace-private.h"
5616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/constitute.h"
5716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/enhance.h"
5816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/exception.h"
5916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/exception-private.h"
6016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/geometry.h"
6116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/histogram.h"
6216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/image.h"
6316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/image-private.h"
6416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/layer.h"
6516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/list.h"
6616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/log.h"
6716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/MagickCore.h"
6816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/memory_.h"
6916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/module.h"
7016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/monitor.h"
7116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/monitor-private.h"
7216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/option.h"
7316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/pixel.h"
7416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/pixel-accessor.h"
7516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/profile.h"
7616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/property.h"
7716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/quantum-private.h"
7816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/resource_.h"
7916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/semaphore.h"
8016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/quantum-private.h"
8116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/static.h"
8216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/statistic.h"
8316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/string_.h"
8416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/string-private.h"
8516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/transform.h"
8616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/utility.h"
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
88286a6355c4544b794da2b6df973faad07c69e541glennrp
897ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp/* Suppress libpng pedantic warnings that were added in
907ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * libpng-1.2.41 and libpng-1.4.0.  If you are working on
91faa852bad40107edae19405e76a299057668d795glennrp * migration to libpng-1.5, remove these defines and then
927ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * fix any code that generates warnings.
937ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp */
94991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp/* #define PNG_DEPRECATED   Use of this function is deprecated */
95faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_USE_RESULT   The result of this function must be checked */
96faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_NORETURN     This function does not return */
97faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_ALLOCATED    The result of the function is new memory */
988371ecc013ff231ce380d8717e517312e62e1f01glennrp/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */
995b927348e949d94f3a64b055eccb03459f115c69glennrp
1005b927348e949d94f3a64b055eccb03459f115c69glennrp/* PNG_PTR_NORETURN does not work on some platforms, in libpng-1.5.x */
10175cfe702843fd25dba7cb241c05fa65957c67129cristy#define PNG_PTR_NORETURN
102286a6355c4544b794da2b6df973faad07c69e541glennrp
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1278e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp       (((color).red == (target).red) && \
1288e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp        ((color).green == (target).green) && \
1298e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp        ((color).blue == (target).blue))
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1328e58efdecda887b08ef730d68290a61081ef2566glennrp/* Macros for left-bit-replication to ensure that pixels
13316ea139d53d867211d3bb0fa859a83de653f687ecristy * and PixelInfos all have the same image->depth, and for use
1348e58efdecda887b08ef730d68290a61081ef2566glennrp * in PNG8 quantization.
1358e58efdecda887b08ef730d68290a61081ef2566glennrp */
1368e58efdecda887b08ef730d68290a61081ef2566glennrp
1378e58efdecda887b08ef730d68290a61081ef2566glennrp
1388e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR01: Replicate top bit */
1398e58efdecda887b08ef730d68290a61081ef2566glennrp
14005001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR01PacketRed(pixelpacket) \
1418e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=(ScaleQuantumToChar((pixelpacket).red) < 0x10 ? \
1428e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1438e58efdecda887b08ef730d68290a61081ef2566glennrp
14491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketGreen(pixelpacket) \
1458e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=(ScaleQuantumToChar((pixelpacket).green) < 0x10 ? \
1468e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1478e58efdecda887b08ef730d68290a61081ef2566glennrp
14891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketBlue(pixelpacket) \
1498e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=(ScaleQuantumToChar((pixelpacket).blue) < 0x10 ? \
1508e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1518e58efdecda887b08ef730d68290a61081ef2566glennrp
15216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PacketAlpha(pixelpacket) \
15316ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=(ScaleQuantumToChar((pixelpacket).alpha) < 0x10 ? \
1548e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1558e58efdecda887b08ef730d68290a61081ef2566glennrp
15691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGB(pixelpacket) \
157bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
15805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR01PacketRed((pixelpacket)); \
15991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketGreen((pixelpacket)); \
16091d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketBlue((pixelpacket)); \
161bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1628e58efdecda887b08ef730d68290a61081ef2566glennrp
16391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGBO(pixelpacket) \
164bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
16591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketRGB((pixelpacket)); \
16616ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PacketAlpha((pixelpacket)); \
167bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1688e58efdecda887b08ef730d68290a61081ef2566glennrp
169ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR01PixelRed(pixel) \
17016ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelRed(image,(pixel))) < 0x10 ? \
1718e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1728e58efdecda887b08ef730d68290a61081ef2566glennrp
17354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelGreen(pixel) \
17416ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelGreen(image,(pixel))) < 0x10 ? \
1758e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1768e58efdecda887b08ef730d68290a61081ef2566glennrp
17754cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelBlue(pixel) \
17816ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelBlue(image,(pixel))) < 0x10 ? \
1798e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1808e58efdecda887b08ef730d68290a61081ef2566glennrp
18116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelAlpha(pixel) \
18216ea139d53d867211d3bb0fa859a83de653f687ecristy        (ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) < 0x10 ? \
1838e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1848e58efdecda887b08ef730d68290a61081ef2566glennrp
18554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelRGB(pixel) \
186bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
187ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR01PixelRed((pixel)); \
18854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelGreen((pixel)); \
18954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelBlue((pixel)); \
190bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1918e58efdecda887b08ef730d68290a61081ef2566glennrp
19216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelRGBA(pixel) \
193bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
19454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelRGB((pixel)); \
19516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PixelAlpha((pixel)); \
196bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1978e58efdecda887b08ef730d68290a61081ef2566glennrp
1988e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR02: Replicate top 2 bits */
1998e58efdecda887b08ef730d68290a61081ef2566glennrp
20005001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR02PacketRed(pixelpacket) \
2018e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2028e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xc0; \
2038e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2048e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2058e58efdecda887b08ef730d68290a61081ef2566glennrp   }
20691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketGreen(pixelpacket) \
2078e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2088e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xc0; \
2098e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2108e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2118e58efdecda887b08ef730d68290a61081ef2566glennrp   }
21291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketBlue(pixelpacket) \
2138e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2148e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xc0; \
2158e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
2168e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2178e58efdecda887b08ef730d68290a61081ef2566glennrp   }
21816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PacketAlpha(pixelpacket) \
2198e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
22016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xc0; \
22116ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum( \
2228e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2238e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2248e58efdecda887b08ef730d68290a61081ef2566glennrp
22591d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGB(pixelpacket) \
226bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
22705001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR02PacketRed((pixelpacket)); \
22891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketGreen((pixelpacket)); \
22991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue((pixelpacket)); \
230bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2318e58efdecda887b08ef730d68290a61081ef2566glennrp
23291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGBO(pixelpacket) \
233bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
23491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketRGB((pixelpacket)); \
23516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PacketAlpha((pixelpacket)); \
236bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2378e58efdecda887b08ef730d68290a61081ef2566glennrp
238ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR02PixelRed(pixel) \
2398e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
24016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
2418e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
24216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
24316ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
24416ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2458e58efdecda887b08ef730d68290a61081ef2566glennrp   }
24654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelGreen(pixel) \
2478e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
24816ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
2498e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
25016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
25116ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
25216ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2538e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelBlue(pixel) \
2558e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2568e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
25716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xc0; \
25816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
25916ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
26016ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2618e58efdecda887b08ef730d68290a61081ef2566glennrp   }
26216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelAlpha(pixel) \
2638e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2648e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
26516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xc0; \
26616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image, ScaleCharToQuantum( \
26716ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
26816ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel) ); \
2698e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2708e58efdecda887b08ef730d68290a61081ef2566glennrp
27154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelRGB(pixel) \
272bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
273ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR02PixelRed((pixel)); \
27454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelGreen((pixel)); \
27554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelBlue((pixel)); \
276bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2778e58efdecda887b08ef730d68290a61081ef2566glennrp
27816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelRGBA(pixel) \
279bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
28054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelRGB((pixel)); \
28116ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PixelAlpha((pixel)); \
282bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2838e58efdecda887b08ef730d68290a61081ef2566glennrp
2848e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR03: Replicate top 3 bits (only used with opaque pixels during
2858e58efdecda887b08ef730d68290a61081ef2566glennrp   PNG8 quantization) */
2868e58efdecda887b08ef730d68290a61081ef2566glennrp
28705001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR03PacketRed(pixelpacket) \
2888e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2898e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xe0; \
2908e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2918e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
2928e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketGreen(pixelpacket) \
2948e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2958e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xe0; \
2968e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2978e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
2988e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketBlue(pixelpacket) \
3008e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3018e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xe0; \
3028e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
3038e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3048e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3058e58efdecda887b08ef730d68290a61081ef2566glennrp
30691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketRGB(pixelpacket) \
307bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
30805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR03PacketRed((pixelpacket)); \
30991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketGreen((pixelpacket)); \
31091d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketBlue((pixelpacket)); \
311bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3128e58efdecda887b08ef730d68290a61081ef2566glennrp
313ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR03PixelRed(pixel) \
3148e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
31516ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3168e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
31716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
31816ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3198e58efdecda887b08ef730d68290a61081ef2566glennrp   }
32016ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Green(pixel) \
3218e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
32216ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3238e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
32416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
32516ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3268e58efdecda887b08ef730d68290a61081ef2566glennrp   }
32716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Blue(pixel) \
3288e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
32916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelBlue(image,(pixel))) \
3308e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
33116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
33216ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3338e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3348e58efdecda887b08ef730d68290a61081ef2566glennrp
33516ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03RGB(pixel) \
336bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
337ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR03PixelRed((pixel)); \
33816ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Green((pixel)); \
33916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Blue((pixel)); \
340bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3418e58efdecda887b08ef730d68290a61081ef2566glennrp
3428e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR04: Replicate top 4 bits */
3438e58efdecda887b08ef730d68290a61081ef2566glennrp
34405001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR04PacketRed(pixelpacket) \
3458e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3468e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xf0; \
3478e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3488e58efdecda887b08ef730d68290a61081ef2566glennrp   }
34991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketGreen(pixelpacket) \
3508e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3518e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xf0; \
3528e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3538e58efdecda887b08ef730d68290a61081ef2566glennrp   }
35491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketBlue(pixelpacket) \
3558e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3568e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xf0; \
3578e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3588e58efdecda887b08ef730d68290a61081ef2566glennrp   }
35916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PacketAlpha(pixelpacket) \
3608e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
36116ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xf0; \
36216ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3648e58efdecda887b08ef730d68290a61081ef2566glennrp
36591d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGB(pixelpacket) \
366bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
36705001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR04PacketRed((pixelpacket)); \
36891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketGreen((pixelpacket)); \
36991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketBlue((pixelpacket)); \
370bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3718e58efdecda887b08ef730d68290a61081ef2566glennrp
37291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGBO(pixelpacket) \
373bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
37491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB((pixelpacket)); \
37516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PacketAlpha((pixelpacket)); \
376bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3778e58efdecda887b08ef730d68290a61081ef2566glennrp
378ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR04PixelRed(pixel) \
3798e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
38016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3818e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
38216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
38316ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3848e58efdecda887b08ef730d68290a61081ef2566glennrp   }
38554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelGreen(pixel) \
3868e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
38716ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3888e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
38916ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
39016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3918e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39254cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelBlue(pixel) \
3938e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3948e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
39516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xf0; \
39616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
39716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3988e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelAlpha(pixel) \
4008e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4018e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
40216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xf0; \
40316ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
40416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4058e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4068e58efdecda887b08ef730d68290a61081ef2566glennrp
40754cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelRGB(pixel) \
408bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
409ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR04PixelRed((pixel)); \
41054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelGreen((pixel)); \
41154cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelBlue((pixel)); \
412bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4138e58efdecda887b08ef730d68290a61081ef2566glennrp
41416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelRGBA(pixel) \
415bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
41654cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelRGB((pixel)); \
41716ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PixelAlpha((pixel)); \
418bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4198e58efdecda887b08ef730d68290a61081ef2566glennrp
4208e58efdecda887b08ef730d68290a61081ef2566glennrp
4218e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR08: Replicate top 8 bits */
4228e58efdecda887b08ef730d68290a61081ef2566glennrp
42305001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR08PacketRed(pixelpacket) \
4248e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4258e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red); \
4268e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits)); \
4278e58efdecda887b08ef730d68290a61081ef2566glennrp   }
42891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketGreen(pixelpacket) \
4298e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4308e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green); \
4318e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits)); \
4328e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketBlue(pixelpacket) \
4348e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4358e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue); \
4368e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits)); \
4378e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PacketAlpha(pixelpacket) \
4398e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
44016ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha); \
44116ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits)); \
4428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4438e58efdecda887b08ef730d68290a61081ef2566glennrp
44491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketRGB(pixelpacket) \
445bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
44605001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR08PacketRed((pixelpacket)); \
44791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketGreen((pixelpacket)); \
44891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketBlue((pixelpacket)); \
449bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4508e58efdecda887b08ef730d68290a61081ef2566glennrp
45191d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketRGBO(pixelpacket) \
452bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
45391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketRGB((pixelpacket)); \
45416ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR08PacketAlpha((pixelpacket)); \
455bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4568e58efdecda887b08ef730d68290a61081ef2566glennrp
457ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR08PixelRed(pixel) \
4588e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4598e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
46016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelRed(image,(pixel))); \
46116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
46216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
46454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelGreen(pixel) \
4658e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4668e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
46716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelGreen(image,(pixel))); \
46816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
46916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4708e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelBlue(pixel) \
4728e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4738e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
47416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))); \
47516ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
47616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4778e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PixelAlpha(pixel) \
4798e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4808e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
48116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))); \
48216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
48316ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4848e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4858e58efdecda887b08ef730d68290a61081ef2566glennrp
48654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelRGB(pixel) \
487bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
488ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR08PixelRed((pixel)); \
48954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelGreen((pixel)); \
49054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelBlue((pixel)); \
491bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4928e58efdecda887b08ef730d68290a61081ef2566glennrp
49316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR08PixelRGBA(pixel) \
494bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
49554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelRGB((pixel)); \
49616ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR08PixelAlpha((pixel)); \
497bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4988e58efdecda887b08ef730d68290a61081ef2566glennrp
4998e58efdecda887b08ef730d68290a61081ef2566glennrp
5008e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR16: Replicate top 16 bits */
5018e58efdecda887b08ef730d68290a61081ef2566glennrp
50205001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR16PacketRed(pixelpacket) \
5038e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5048e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).red); \
5058e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleShortToQuantum((lbr_bits)); \
5068e58efdecda887b08ef730d68290a61081ef2566glennrp   }
50791d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketGreen(pixelpacket) \
5088e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5098e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).green); \
5108e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleShortToQuantum((lbr_bits)); \
5118e58efdecda887b08ef730d68290a61081ef2566glennrp   }
51291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketBlue(pixelpacket) \
5138e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5148e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).blue); \
5158e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleShortToQuantum((lbr_bits)); \
5168e58efdecda887b08ef730d68290a61081ef2566glennrp   }
51716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PacketAlpha(pixelpacket) \
5188e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
51916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).alpha); \
52016ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleShortToQuantum((lbr_bits)); \
5218e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5228e58efdecda887b08ef730d68290a61081ef2566glennrp
52391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketRGB(pixelpacket) \
524bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
52505001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR16PacketRed((pixelpacket)); \
52691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketGreen((pixelpacket)); \
52791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketBlue((pixelpacket)); \
528bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5298e58efdecda887b08ef730d68290a61081ef2566glennrp
53091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketRGBO(pixelpacket) \
531bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
53291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketRGB((pixelpacket)); \
53316ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR16PacketAlpha((pixelpacket)); \
534bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5358e58efdecda887b08ef730d68290a61081ef2566glennrp
536ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR16PixelRed(pixel) \
5378e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5388e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
53916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelRed(image,(pixel))); \
54016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
54116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
54354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelGreen(pixel) \
5448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5458e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
54616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelGreen(image,(pixel))); \
54716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
54816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5498e58efdecda887b08ef730d68290a61081ef2566glennrp   }
55054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelBlue(pixel) \
5518e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5528e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
55316ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelBlue(image,(pixel))); \
55416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
55516ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5568e58efdecda887b08ef730d68290a61081ef2566glennrp   }
55716ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PixelAlpha(pixel) \
5588e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5598e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
56016ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToShort(GetPixelAlpha(image,(pixel))); \
56116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
56216ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5648e58efdecda887b08ef730d68290a61081ef2566glennrp
56554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelRGB(pixel) \
566bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
567ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR16PixelRed((pixel)); \
56854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelGreen((pixel)); \
56954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelBlue((pixel)); \
570bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5718e58efdecda887b08ef730d68290a61081ef2566glennrp
57216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR16PixelRGBA(pixel) \
573bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
57454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelRGB((pixel)); \
57516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR16PixelAlpha((pixel)); \
576bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5778e58efdecda887b08ef730d68290a61081ef2566glennrp
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
587edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
589cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  *ping_semaphore = (SemaphoreInfo *) NULL;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
626bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
64185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
64285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
64385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
64485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
64585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
64685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
64785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
64885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
64985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
65085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
65185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
65285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
65385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
65485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
65585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
65685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
65785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
65885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
65985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
66085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
66185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
66285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
66385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
66485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
66585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
66685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
66785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
66885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
66985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
67085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
67185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
67285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
67385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
67685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
67785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
67885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
67985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
68085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
68185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
68685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
68785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
68885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
68985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
69085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
69185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
69285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
69385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
794bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84035ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
850b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
851b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
852b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
8701868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_level,
8711868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_strategy,
8721868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_filter,
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
878bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90716ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
91126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
91226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
91326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
914a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
91526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
91626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
91726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
91826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
91926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
92026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
92126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
92226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
923a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
92426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
92526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
9268d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_exclude_zTXt,
9278d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap;
92826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
93616ea139d53d867211d3bb0fa859a83de653f687ecristy  WritePNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9370c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
93916ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteMNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
94316ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteJNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
9470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
948fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
9500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
95116ea139d53d867211d3bb0fa859a83de653f687ecristyLosslessReduceDepthOK(Image *image,ExceptionInfo *exception)
9520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
9539d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp    /* Reduce bit depth if it can be reduced losslessly from 16+ to 8.
95467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
95567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * This is true if the high byte and the next highest byte of
95667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * each sample of the image, the colormap, and the background color
9573faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are equal to each other.  We check this by seeing if the samples
9583faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are unchanged when we scale them down to 8 and back up to Quantum.
95967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
96067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * We don't use the method GetImageDepth() because it doesn't check
9613faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * background and doesn't handle PseudoClass specially.
9629d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp     */
96305a549971fd661147ade177e2bc10f6cfcfc32b4glennrp
9643faa9a3fb01696daaf976d595f492cb530bffb21glennrp#define QuantumToCharToQuantumEqQuantum(quantum) \
9653faa9a3fb01696daaf976d595f492cb530bffb21glennrp  ((ScaleCharToQuantum((unsigned char) ScaleQuantumToChar(quantum))) == quantum)
9663faa9a3fb01696daaf976d595f492cb530bffb21glennrp
96767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    MagickBooleanType
96867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      ok_to_reduce=MagickFalse;
96967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
97003e11f6e8d7f01a32b53d7e8e6a3bfd5ef1c5c9dglennrp    if (image->depth >= 16)
9710c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
9720c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
97316ea139d53d867211d3bb0fa859a83de653f687ecristy        const Quantum
9740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
9750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9760c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
9773faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.red) &&
9783faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.green) &&
9793faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.blue) ?
9803faa9a3fb01696daaf976d595f492cb530bffb21glennrp           MagickTrue : MagickFalse;
9810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
9830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
9840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
9850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
9870c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
9883faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=(
9893faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9903faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].red) &&
9913faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9923faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].green) &&
9933faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9943faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].blue)) ?
9953faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
9963faa9a3fb01696daaf976d595f492cb530bffb21glennrp
9970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
9983faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   break;
9990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
10000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
10010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
10030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
10040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
10050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
10060c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
10070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10080c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
10090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
10100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
10120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
101316ea139d53d867211d3bb0fa859a83de653f687ecristy              p=GetVirtualPixels(image,0,y,image->columns,1,exception);
10140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
101516ea139d53d867211d3bb0fa859a83de653f687ecristy              if (p == (const Quantum *) NULL)
10160c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
10170c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
10180c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
10200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
10220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
10233faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=
102416ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelRed(image,p)) &&
102516ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelGreen(image,p)) &&
102616ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelBlue(image,p)) ?
10273faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
10280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
10300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
103216ea139d53d867211d3bb0fa859a83de653f687ecristy                p+=GetPixelChannels(image);
10330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
10348640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
10350c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
10360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
10370c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
10380c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
10400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
10410c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1042fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    OK to reduce PNG bit depth to 8 without loss of info");
10430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
1044a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
1045a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
1046a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1047fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    Not OK to reduce PNG bit depth to 8 without loss of info");
1048a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
10490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
10500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
10520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
10530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
10540c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10551a56e9c9268976936eeab9fe97eb664b847e444cglennrpstatic const char* PngColorTypeToString(const unsigned int color_type)
10561a56e9c9268976936eeab9fe97eb664b847e444cglennrp{
10571a56e9c9268976936eeab9fe97eb664b847e444cglennrp  const char
10581a56e9c9268976936eeab9fe97eb664b847e444cglennrp    *result = "Unknown";
10591a56e9c9268976936eeab9fe97eb664b847e444cglennrp
10601a56e9c9268976936eeab9fe97eb664b847e444cglennrp  switch (color_type)
10611a56e9c9268976936eeab9fe97eb664b847e444cglennrp    {
10621a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY:
10631a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray";
10641a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10651a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY_ALPHA:
10661a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray+Alpha";
10671a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10681a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_PALETTE:
10691a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Palette";
10701a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10711a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB:
10721a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB";
10731a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10741a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB_ALPHA:
10751a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB+Alpha";
10761a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
10771a56e9c9268976936eeab9fe97eb664b847e444cglennrp    }
10781a56e9c9268976936eeab9fe97eb664b847e444cglennrp
10791a56e9c9268976936eeab9fe97eb664b847e444cglennrp  return result;
10801a56e9c9268976936eeab9fe97eb664b847e444cglennrp}
10811a56e9c9268976936eeab9fe97eb664b847e444cglennrp
1082e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
1083cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
10840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1085e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
1086e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1087e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
1088e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
10890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1090e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
1091e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
10920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1093e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
1094e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
10950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1096e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
1097e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
10980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1099e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1100e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
1101e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
1102e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1103e610a071534e448c46460a5aa39ede33bf56b329glennrp
1104e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
1105cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_from_PNG_RenderingIntent(const int ping_intent)
11060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1107cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  switch (ping_intent)
1108e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1109e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
1110e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
11110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1112e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
1113e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
11140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1115e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
1116e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
11170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1118e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
1119e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
11200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1121e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1122e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
1123e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
1124e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1125e610a071534e448c46460a5aa39ede33bf56b329glennrp
11269d8c12213abd15fee2d84da62d3e5145d9db06cdcristystatic const char *
112798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrpMagick_RenderingIntentString_from_PNG_RenderingIntent(const int ping_intent)
112898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp{
112998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  switch (ping_intent)
113098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
113198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 0:
113298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Perceptual Intent";
113398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
113498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 1:
113598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Relative Intent";
113698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
113798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 2:
113898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Saturation Intent";
113998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
114098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 3:
114198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Absolute Intent";
114298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
114398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    default:
114498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Undefined Intent";
114598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
114698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp}
114798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
1148bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
11520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
1156d9ecd04e9c567113b4b605cf76681cbb37c093cdcristystatic const char *
11575dff435eceea4f80207a906b11e65aed48fe3f27glennrpMagick_ColorType_from_PNG_ColorType(const int ping_colortype)
11585dff435eceea4f80207a906b11e65aed48fe3f27glennrp{
11595dff435eceea4f80207a906b11e65aed48fe3f27glennrp  switch (ping_colortype)
11605dff435eceea4f80207a906b11e65aed48fe3f27glennrp  {
11615dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 0:
11625dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Grayscale";
11635dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11645dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 2:
11655dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Truecolor";
11665dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11675dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 3:
11685dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Indexed";
11695dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11705dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 4:
11715dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "GrayAlpha";
11725dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11735dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 6:
11745dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "RGBA";
11755dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11765dff435eceea4f80207a906b11e65aed48fe3f27glennrp    default:
11775dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "UndefinedColorType";
11785dff435eceea4f80207a906b11e65aed48fe3f27glennrp    }
11795dff435eceea4f80207a906b11e65aed48fe3f27glennrp}
11805dff435eceea4f80207a906b11e65aed48fe3f27glennrp
11815dff435eceea4f80207a906b11e65aed48fe3f27glennrp
1182bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
11860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1189d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1307d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1308bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1330a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1338a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135103812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
135203812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1356e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
1357e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1359d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1365d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
1447f54e295d6fa414fa04aa4f43767c20eda8ae555eglennrp%    the original PNG from files that have been converted to Xcode-PNG,
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14783b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy          (void) FormatLocaleString(msg,MaxTextExtent,
1479e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1480e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1508bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
15240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
15270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
15850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
16100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
16180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
16330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
16380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1653bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
165721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
165821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
166021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1662bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
16670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
16710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
16850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
16880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
16910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
16940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1706bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1709bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1727bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17298182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
17308182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
17310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17418182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
174616ea139d53d867211d3bb0fa859a83de653f687ecristytypedef struct _PNGErrorInfo
174716ea139d53d867211d3bb0fa859a83de653f687ecristy{
174816ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
174916ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
175016ea139d53d867211d3bb0fa859a83de653f687ecristy
175116ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
175216ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
175316ea139d53d867211d3bb0fa859a83de653f687ecristy} PNGErrorInfo;
175416ea139d53d867211d3bb0fa859a83de653f687ecristy
1755cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
175716ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
175816ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
175916ea139d53d867211d3bb0fa859a83de653f687ecristy
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
176316ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
176416ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
17650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
176616ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
176716ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
176816ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
1769c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy
177016ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
177116ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
177216ea139d53d867211d3bb0fa859a83de653f687ecristy
177316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,message,
177416ea139d53d867211d3bb0fa859a83de653f687ecristy    "`%s'",image->filename);
17750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1776e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
17778371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
17788371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
17798371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1781faa852bad40107edae19405e76a299057668d795glennrp#else
1782faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1783faa852bad40107edae19405e76a299057668d795glennrp#endif
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1786cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
178816ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
178916ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
179016ea139d53d867211d3bb0fa859a83de653f687ecristy
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
179416ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
179516ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
179616ea139d53d867211d3bb0fa859a83de653f687ecristy
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
17990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
180016ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
180116ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
180216ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
180316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
180416ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
18050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
180616ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1811a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
1812a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_alloc_size_t size)
1813a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
1814a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_size_t size)
1815a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1817df0d90e1d3bbfa3956818ac7bf43aa0d008020dccristy  (void) png_ptr;
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1824cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
18263bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) png_ptr;
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1837edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrpMagick_png_read_raw_profile(png_struct *ping,Image *image,
1838edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   const ImageInfo *image_info, png_textp text,int ii,ExceptionInfo *exception)
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1840bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1873f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
18740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
187597f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
187697f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
187797f90e23c85b9c58387880125c29d8c99126f83aglennrp
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1884edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping,"invalid profile length");
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18888723e4bcd840478cecfd29891e792edb499cd0e9cristy  profile=BlobToStringInfo((const void *) NULL,length);
18890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1892edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping, "unable to copy profile");
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
18990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1900bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1906edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp          png_warning(ping, "ran out of profile data");
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
19150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
192216ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProfile(image,&text[ii].key[17],profile,exception);
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
19240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
19270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1961bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
19630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1964bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2012cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tIME chunk into the date:modify property */
2013cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tEXt/Creation Time chunk into the date:create property */
2014cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
201998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    intent, /* "PNG Rendering intent", which is ICC intent + 1 */
2020cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
20224eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
2024913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp    number_colors,
2025faa852bad40107edae19405e76a299057668d795glennrp    pass,
2026faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
2027faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
2028faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
2029faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
2030faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
20314eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
20324eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
20334eb3931feb349dd87142c78503b779228f3e1a0fglennrp
20344eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
20354eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
20384383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
203998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_cHRM,
204098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_gAMA,
204198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_iCCP,
204298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_sRGB,
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
204516ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
204616ea139d53d867211d3bb0fa859a83de653f687ecristy    transparent_color;
204716ea139d53d867211d3bb0fa859a83de653f687ecristy
204816ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
204916ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
205016ea139d53d867211d3bb0fa859a83de653f687ecristy
2051faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
2052faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
2053faa852bad40107edae19405e76a299057668d795glennrp
2054faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
2055faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
2056faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
2057faa852bad40107edae19405e76a299057668d795glennrp
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2068faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
2069faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
2070faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
20714eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
20724eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
2073faa852bad40107edae19405e76a299057668d795glennrp
207416ea139d53d867211d3bb0fa859a83de653f687ecristy  QuantumInfo
207516ea139d53d867211d3bb0fa859a83de653f687ecristy    *quantum_info;
207616ea139d53d867211d3bb0fa859a83de653f687ecristy
2077bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2078756ae430d36380dfab8ca703538f5922f3796351cristy    ping_rowbytes,
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2084bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
208816ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
209239992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2095eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
2096eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
2097eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
209875fc68f33e6e766a22e8ed653c3ed50b0d142827cristy  unsigned char
209975fc68f33e6e766a22e8ed653c3ed50b0d142827cristy    *volatile ping_pixels;
210055b78b53f1e013e0af19565ac04aaa7660d53795cristy
2101629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
2110629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_APNG_SUPPORTED /* libpng was built with APNG patch; */
2111629960f505ebba710ec9b6953a539a21dab176f2glennrp                          /* ignore the APNG chunks */
2112629960f505ebba710ec9b6953a539a21dab176f2glennrp     97,  99,  84,  76, (png_byte) '\0',   /* acTL */
2113629960f505ebba710ec9b6953a539a21dab176f2glennrp    102,  99,  84,  76, (png_byte) '\0',   /* fcTL */
2114629960f505ebba710ec9b6953a539a21dab176f2glennrp    102, 100,  65,  84, (png_byte) '\0',   /* fdAT */
2115629960f505ebba710ec9b6953a539a21dab176f2glennrp#endif
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
2120fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
212225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
212861b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
212961b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
213061b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
213161b4c957269727a0a2526edc2331881da8346100glennrp    {
213261b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
213361b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
213461b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
213561b4c957269727a0a2526edc2331881da8346100glennrp    }
213661b4c957269727a0a2526edc2331881da8346100glennrp#  endif
213761b4c957269727a0a2526edc2331881da8346100glennrp#endif
213861b4c957269727a0a2526edc2331881da8346100glennrp
213916ea139d53d867211d3bb0fa859a83de653f687ecristy
214016ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info = (QuantumInfo *) NULL;
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2143a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
214498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
2145a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
21468a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      "  image->alpha_trait=%d",(int) image->alpha_trait);
2147a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
214898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
214998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      "  image->rendering_intent=%d",(int) image->rendering_intent);
2150e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
2151e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2152e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp      "  image->colorspace=%d",(int) image->colorspace);
215398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  }
215498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  intent=Magick_RenderingIntent_to_PNG_RenderingIntent(image->rendering_intent);
215598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
21560e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
21570e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
21580e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
21590e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
216016ea139d53d867211d3bb0fa859a83de653f687ecristy  transparent_color.alpha=65537;
21610e319739731741c52a6303723e0c8678a0df5579glennrp
2162913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp  number_colors=0;
2163cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
21644eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
2165cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
2166cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
216798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_cHRM = MagickFalse;
216898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_gAMA = MagickFalse;
216998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_iCCP = MagickFalse;
217098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_sRGB = MagickFalse;
217198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
217616ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
217716ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
217816ea139d53d867211d3bb0fa859a83de653f687ecristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
2179cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
2180cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
218216ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,&error_info,
2183cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
21890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
21970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2204cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
22050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2206faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2212edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2213edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
2214cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2216edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2217edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (ping_pixels != (unsigned char *) NULL)
2218edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
2219edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
22230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
22257b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
222616ea139d53d867211d3bb0fa859a83de653f687ecristy          InheritException(exception,exception);
22277b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
22287b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
22290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2232edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2233edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
2234edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
2235edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
2236edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
2237edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2238edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
2239edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
2240edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
2241edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2245faa852bad40107edae19405e76a299057668d795glennrp
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
22480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22819bf97b6c2143eb20c330346b01e82102cc082725glennrp#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
22829bf97b6c2143eb20c330346b01e82102cc082725glennrp    /* Disable new libpng-1.5.10 feature */
22839bf97b6c2143eb20c330346b01e82102cc082725glennrp    png_set_check_for_invalid_index (ping, 0);
22849bf97b6c2143eb20c330346b01e82102cc082725glennrp#endif
22859bf97b6c2143eb20c330346b01e82102cc082725glennrp
2286991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2287991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2288991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2302991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2306faa852bad40107edae19405e76a299057668d795glennrp
2307faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2308faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2309faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2310faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2311faa852bad40107edae19405e76a299057668d795glennrp
2312faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2313faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2314faa852bad40107edae19405e76a299057668d795glennrp
2315faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2316faa852bad40107edae19405e76a299057668d795glennrp
2317faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2319faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
2320faa852bad40107edae19405e76a299057668d795glennrp        {
2321faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
2322faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
2323faa852bad40107edae19405e76a299057668d795glennrp        }
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2325faa852bad40107edae19405e76a299057668d795glennrp
2326faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2328faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
232998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2330176b29a003f11fd934137871d574995319408665cristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2331176b29a003f11fd934137871d574995319408665cristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2332176b29a003f11fd934137871d574995319408665cristy    {
2333176b29a003f11fd934137871d574995319408665cristy      image->rendering_intent=UndefinedIntent;
233498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      intent=Magick_RenderingIntent_to_PNG_RenderingIntent(UndefinedIntent);
2335176b29a003f11fd934137871d574995319408665cristy      image->gamma=1.000;
2336176b29a003f11fd934137871d574995319408665cristy      (void) ResetMagickMemory(&image->chromaticity,0,
2337176b29a003f11fd934137871d574995319408665cristy        sizeof(image->chromaticity));
2338176b29a003f11fd934137871d574995319408665cristy    }
233998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2343e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
2344e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
23450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
2348faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
23490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
2352faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
23530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
2356faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
235998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
236098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
236198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_gAMA=MagickTrue;
236298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
236398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
236498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG gAMA chunk.");
236598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
236698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
236798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
236898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
236998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_cHRM=MagickTrue;
237098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
237198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
237298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG cHRM chunk.");
237398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
237498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
237598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
237698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
237798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_iCCP=MagickTrue;
237898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
237998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
238098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG iCCP chunk.");
238198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
238298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
238398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
238498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
238598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_sRGB=MagickTrue;
238698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
238798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
238898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG sRGB chunk.");
238998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
239098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2391faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2392faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2397e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2398e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2399e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2400e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2401e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2402e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2403e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2404e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
24130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
2422e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          profile=BlobToStringInfo(info,profile_length);
2423e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          if (profile == (StringInfo *) NULL)
2424edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2425edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              png_warning(ping, "ICC profile is NULL");
2426edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              profile=DestroyStringInfo(profile);
2427edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2428edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp          else
2429edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2430edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              (void) SetImageProfile(image,"icc",profile,exception);
2431edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              profile=DestroyStringInfo(profile);
2432edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
24392ea7a8e883de7623d345f32f90ee99248a4a867ecristy      {
24402ea7a8e883de7623d345f32f90ee99248a4a867ecristy        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
24412ea7a8e883de7623d345f32f90ee99248a4a867ecristy          (mng_info->global_srgb_intent);
24422ea7a8e883de7623d345f32f90ee99248a4a867ecristy      }
24430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2446cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
2447cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
24480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2451e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2456faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2457faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2458faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
24590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
246898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2469faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2470faa852bad40107edae19405e76a299057668d795glennrp    {
2471faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2472faa852bad40107edae19405e76a299057668d795glennrp        {
2473faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2474faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2475faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2476faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2477faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2478faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2479faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2480faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2481faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2482faa852bad40107edae19405e76a299057668d795glennrp        }
2483faa852bad40107edae19405e76a299057668d795glennrp    }
24840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2485faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
24960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2499e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
25003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2501e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
2502cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
2503cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
2504da7803d6b1161960bc1e7db4d9718284c116fab8cristy      png_set_gAMA(ping,ping_info,1.000f/2.200f);
2505faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
2506faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
2507faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2510faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2512905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2513905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
25140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2518e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2519e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2523faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2524faa852bad40107edae19405e76a299057668d795glennrp    {
2525faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2526faa852bad40107edae19405e76a299057668d795glennrp        {
2527faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2528faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2529faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2530faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2531faa852bad40107edae19405e76a299057668d795glennrp        }
2532faa852bad40107edae19405e76a299057668d795glennrp    }
2533faa852bad40107edae19405e76a299057668d795glennrp
2534faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
25400881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
254116ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.x=(double) x_resolution;
254216ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.y=(double) y_resolution;
25430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
254716ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.x=(double) x_resolution/100.0;
254816ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.y=(double) y_resolution/100.0;
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
25500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2553e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2554e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2557823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2558faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
25640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2566faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
25720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2573faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2574edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              {
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
2577edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                    png_warning(ping,
2578edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                      "global tRNS has more entries than global PLTE");
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2580edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                else
2581edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  {
2582edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                     png_set_tRNS(ping,ping_info,mng_info->global_trns,
2583edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                       (int) mng_info->global_trns_length,NULL);
2584edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  }
2585edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               }
2586bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2591faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2600faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2601faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
26020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
26050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
26080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
26110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2612c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2613c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2614c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2620edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"No global PLTE in file");
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2624bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2625faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2626faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
26280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2629faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2631bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2632bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2633bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
26400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2641bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      /* Scale background components to 16-bit, then scale
2642bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2643bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
2644bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2645bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2646bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    raw ping_background=(%d,%d,%d).",ping_background->red,
2647bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            ping_background->green,ping_background->blue);
26482cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2649bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
26500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2651bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (ping_bit_depth == 1)
2652bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
26530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2654bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        else if (ping_bit_depth == 2)
2655bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
26560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2657bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        else if (ping_bit_depth == 4)
2658bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
26590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2660bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (ping_bit_depth <= 8)
2661bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
26622cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2663bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2664bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2665bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
26662cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2667bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2668bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
26692cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26702cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
26710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26722cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26732cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
26742cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
2675bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
26762cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2677bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2678faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
26790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2680bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2681faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
26820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2683bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2684bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
26850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
268616ea139d53d867211d3bb0fa859a83de653f687ecristy        image->background_color.alpha=OpaqueAlpha;
26872cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2688bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2689bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2690bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2691bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2692bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2693bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2695bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2696a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2697faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2700a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
270535ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
270635ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
270735ef824baa82511126ff0072ae30eee0da9c05a3cristy
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2712f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2714faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2715faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2716faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2717faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2718faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2719faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2725faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
27268a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          image->alpha_trait=UndefinedPixelTrait;
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2730a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2731a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2732a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2733a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2734a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2735a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2736a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2737a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2738a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
273916ea139d53d867211d3bb0fa859a83de653f687ecristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
274005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2741faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27430f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
27440f111984738842d27d04aed2a3f823d82a943506glennrp              {
27450f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27460f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
27470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27480f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
274916ea139d53d867211d3bb0fa859a83de653f687ecristy                  "    scaled graylevel is %.20g.",transparent_color.alpha);
27500f111984738842d27d04aed2a3f823d82a943506glennrp              }
275116ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.red=transparent_color.alpha;
275216ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.green=transparent_color.alpha;
275316ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.blue=transparent_color.alpha;
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2760faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2765faa852bad40107edae19405e76a299057668d795glennrp
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2767faa852bad40107edae19405e76a299057668d795glennrp
2768faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2769faa852bad40107edae19405e76a299057668d795glennrp
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2779faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2780faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2791faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2792faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2793a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
279416ea139d53d867211d3bb0fa859a83de653f687ecristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
279516ea139d53d867211d3bb0fa859a83de653f687ecristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
27968d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    {
2797e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp      if ((!png_get_valid(ping,ping_info,PNG_INFO_gAMA) ||
2798e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp          image->gamma == 1.0) &&
27998d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          !png_get_valid(ping,ping_info,PNG_INFO_cHRM) &&
28008d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          !png_get_valid(ping,ping_info,PNG_INFO_sRGB))
28018d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        {
28028d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          /* Set image->gamma to 1.0, image->rendering_intent to Undefined,
2803e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp           * image->colorspace to GRAY, and reset image->chromaticity.
28048d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp           */
28058d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          SetImageColorspace(image,GRAYColorspace,exception);
28068d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        }
28078d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    }
2808e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
2809e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp  (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2810e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp      "  image->colorspace=%d",(int) image->colorspace);
2811a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
2812faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
281332340ffa74550819f755f966e397ed58bbccd8e5glennrp      ((int) ping_bit_depth < 16 &&
281432340ffa74550819f755f966e397ed58bbccd8e5glennrp      (int) ping_color_type == PNG_COLOR_TYPE_GRAY))
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2816befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2817befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2818befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2820befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2821befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
282467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
282567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
282667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
282767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2829faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
28333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2835bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
28360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
28403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
284816ea139d53d867211d3bb0fa859a83de653f687ecristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
2849edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
28500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2851faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
28570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28586af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
28593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
28646af6cf1a950b111ad0ac706269a703086693ba71glennrp
286567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
28666af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
28676af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
28686af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
28696af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
28706af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2875bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2878faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
28790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
28820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
28853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
28863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
28883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2891147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2892cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
2893cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
2894147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
2895147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
2896147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2897147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     /* encode ping_width, ping_height, ping_bit_depth, ping_color_type,
2898147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
2899147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
29003b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,
29017cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
290216ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.width,height    ",msg,exception);
2903147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
29043b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
290516ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.bit_depth       ",msg,exception);
2906147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
29075dff435eceea4f80207a906b11e65aed48fe3f27glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d (%s)",
29085dff435eceea4f80207a906b11e65aed48fe3f27glennrp         (int) ping_color_type,
29095dff435eceea4f80207a906b11e65aed48fe3f27glennrp         Magick_ColorType_from_PNG_ColorType((int)ping_color_type));
291016ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SetImageProperty(image,"png:IHDR.color_type      ",msg,exception);
2911147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2912913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (ping_interlace_method == 0)
2913913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
2914913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Not interlaced)",
2915913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
2916913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
2917913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else if (ping_interlace_method == 1)
2918913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
2919913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Adam7 method)",
2920913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
2921913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
2922913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else
2923913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
2924913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Unknown method)",
2925913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
2926913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
2927913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
2928913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp
2929913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (number_colors != 0)
2930913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
2931913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d",
2932913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) number_colors);
2933913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) SetImageProperty(image,"png:PLTE.number_colors   ",msg,
2934913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            exception);
2935913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
2936cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
2937147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
29430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29440ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2945347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2946347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29481b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
29491b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
29501b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
29511b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2954e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2957edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2958edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
2959cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2961edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
29650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
29720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
2974cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2975cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
29760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2978cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
2979cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
29800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2981cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
2982edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation failed");
29830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
299016ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info=AcquireQuantumInfo(image_info,image);
299116ea139d53d867211d3bb0fa859a83de653f687ecristy
299216ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
2993edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping,"Failed to allocate quantum_info");
29940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2995c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2996c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2997c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2998c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2999c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3000c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
3001c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3004c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
3005c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3006c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
3007c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
3008c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
30098a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
3010c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
3011c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3012b0a657e13c4aefba39c51292005427b47277869dcristy            BlendPixelTrait : UndefinedPixelTrait;
30130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3014c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
3015c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
3016c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
3017c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
30180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3019c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
3020c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
30210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3022cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
3023862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
302516ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
3026c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
30270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
302816ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
302916ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
303016ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
30310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
303216ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
303316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
303416ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
30350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
303616ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
303716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
303816ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
30390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
304016ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
304116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
304216ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
30430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
304416ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
304516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
304616ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
30473faa9a3fb01696daaf976d595f492cb530bffb21glennrp
3048c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
3049c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3050c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
3051a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
3052a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3053a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
3054a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3055c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3056c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
30575aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
30585aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
305916ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
3060c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
3061a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3062a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3063a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
3064a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3065c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
3066c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
3067c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
30684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
30694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
307016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
307116ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
307216ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
307316ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
307416ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
307516ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
30764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
3077a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3078a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3079a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
30804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
30814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
30824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
308316ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
3084c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
3085c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
30860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3087c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
3088c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3089c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
3090c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
30910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3092c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
3093c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
3094c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
3095c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
3096c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
3097c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
30980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3099c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
31007a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3101c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
31027a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
31037a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
31047a287bfadeadea12e47c2376ca78a5d101687142cristy          }
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3109c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3121c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3122c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3123c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
312416ea139d53d867211d3bb0fa859a83de653f687ecristy
31258a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
3126b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
31270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
3129b0a657e13c4aefba39c51292005427b47277869dcristy        (image->alpha_trait  == BlendPixelTrait?  2 : 1)*
3130b0a657e13c4aefba39c51292005427b47277869dcristy        sizeof(*quantum_scanline));
31310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
3133edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
31340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3135bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3138faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3139c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3142c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3143cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
31450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
314616ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
31480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3149cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3151c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3152faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3156bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3159bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
3162a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
31650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3168bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
3169a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
31710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
317447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3177bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
3179a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 6) & 0x03;
3180a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 4) & 0x03;
3181a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 2) & 0x03;
3182a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++) & 0x03;
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
31840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3187bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
3188a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
31900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
319347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3196bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
3198a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 4) & 0x0f;
3199a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++) & 0x0f;
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
32010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
3203a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++ >> 4) & 0x0f;
32040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
320747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3210faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3211bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3213a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
321416ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) *p++),q);
321516ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetPixelAlpha(image,q) != OpaqueAlpha)
32160b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
321716ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
32190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3221bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3222a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
32230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
322647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3230a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
3231c17d96f447438bb27d874f1440ed05f6493fde1fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
323258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              size_t
323358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
323458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
323558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3236c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
323758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
323858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3239c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
324058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
324158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3242c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
324358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
32440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3245faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3247c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3248c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3249c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3250c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3251c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3252c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
325316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,ScaleShortToQuantum(quantum),q);
325416ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
325558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
325616ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
325758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
325858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
325958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
326058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
326158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
326247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
326358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
326458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
326516ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
326616ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
32670b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
326858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
326916ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3272a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
327347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
327647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32803faa9a3fb01696daaf976d595f492cb530bffb21glennrp
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
32850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
328616ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
328716ea139d53d867211d3bb0fa859a83de653f687ecristy
328816ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
328916ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3290bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
329116ea139d53d867211d3bb0fa859a83de653f687ecristy        {
329216ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
329316ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
329416ea139d53d867211d3bb0fa859a83de653f687ecristy        }
32950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
32980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32997a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
33007a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3301cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
33029fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
330347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33047a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
33057a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
33067a287bfadeadea12e47c2376ca78a5d101687142cristy          }
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3308c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
33097a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
331247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3316c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3319c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3320b0a657e13c4aefba39c51292005427b47277869dcristy    image->alpha_trait=found_transparent_pixel ? BlendPixelTrait :
3321b0a657e13c4aefba39c51292005427b47277869dcristy      UndefinedPixelTrait;
3322c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3323c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3324c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3325c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3326c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3327c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3328c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
33295aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
33305aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33315aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3332bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
33335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
33345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3335c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3336c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3337c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
333816ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
333916ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
334016ea139d53d867211d3bb0fa859a83de653f687ecristy
33415c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
33425c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3343b0a657e13c4aefba39c51292005427b47277869dcristy      PixelTrait
3344b0a657e13c4aefba39c51292005427b47277869dcristy        alpha_trait;
33455c6f789db7a30bad01ace12b09ad9cd471339e94cristy
3346b0a657e13c4aefba39c51292005427b47277869dcristy      alpha_trait=image->alpha_trait;
33478a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
334816ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3349b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait=alpha_trait;
33505c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
335147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33524eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3355bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3358cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
336016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
3361edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
3362cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
336947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3370faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
33798a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=BlendPixelTrait;
3380c11cf6a442f3046940608a5743a68cc891deb13eglennrp
33813c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3382c11cf6a442f3046940608a5743a68cc891deb13eglennrp
33830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
33840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
33850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3386c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
33870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
33880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
33898a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                 image->colormap[x].alpha_trait=BlendPixelTrait;
339016ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
339116ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
33920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3393c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
339447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
33960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
33970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
33980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
33990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
340016ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
34010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
34028a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->colormap[x].alpha_trait=BlendPixelTrait;
340316ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
34040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
34050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
34060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
340716ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
34080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
340947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3410a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3411a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3412a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
34130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
34140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
34150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
34160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
34170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
34180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3419c11cf6a442f3046940608a5743a68cc891deb13eglennrp
342016ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
34210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3422c11cf6a442f3046940608a5743a68cc891deb13eglennrp
34230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3424a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3425a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3426a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
34270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
34280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
342916ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
343016ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
343116ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
343216ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
343316ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
343416ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
34354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
343616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
34374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
34380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
343967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
34400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
34414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
344216ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
34434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3444a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
34450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
344616ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
34470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
34480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
34500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3451c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
34520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3453a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3454c11cf6a442f3046940608a5743a68cc891deb13eglennrp
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
34573c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3458eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
34594eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
34604eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3461a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3462a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
34634eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3464a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3465a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34674eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
34684eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
34694eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
34704eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
34710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34724eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
34734eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34744eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
34750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34764eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
34774eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
3478edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            (void) Magick_png_read_raw_profile(ping,image,image_info,text,
3479edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               (int) i,exception);
34804eb3931feb349dd87142c78503b779228f3e1a0fglennrp            num_raw_profiles++;
34814eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
34824eb3931feb349dd87142c78503b779228f3e1a0fglennrp
34834eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
34844eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
34854eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
34864eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
34874eb3931feb349dd87142c78503b779228f3e1a0fglennrp
34884eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
34894eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
34904eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
34914eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
34924eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
3493edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"Memory allocation failed");
34944eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
34954eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
34964eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
34974eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
34984eb3931feb349dd87142c78503b779228f3e1a0fglennrp
34994eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
35004eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
35014eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
35024eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
35034eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
35044eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
350516ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35074eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
35094eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35104eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      length: %lu",(unsigned long) length);
35114eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35124eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      Keyword: %s",text[i].key);
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
35140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35154eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
351697f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
35174eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
35184eb3931feb349dd87142c78503b779228f3e1a0fglennrp      num_text_total += num_text;
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35203c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
353373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
35340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
354147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
3546edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp             png_error(ping,"Memory allocation failed");
35470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
3549edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping,"Cannot overwrite frozen MNG object buffer");
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
35510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
35580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
356016ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
35610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
35640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
3566edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping, "Cloning image for object buffer failed");
35670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3568faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
35700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3571faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3572faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3573faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3574faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3575faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3576faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3577faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3578faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
35790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3580faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
35903c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
359647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
36020a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
36038a46d827a124555f0c48fb2368ec1bba8e079ab6cristy   /* Set image->alpha_trait to MagickTrue if the input colortype supports
36040a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
36050a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
36060a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
36078a46d827a124555f0c48fb2368ec1bba8e079ab6cristy    image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
36080a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
36090a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3610b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
36110a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3612cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3613cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3614cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3615cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3616cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36174eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3618cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3619cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
36203b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3621613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
362216ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text                 ",msg,
362316ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3624cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3625cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3626cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3627cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
36283b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3629cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
363016ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
363116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3632cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3633cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
363498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_cHRM != MagickFalse)
36355961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
36363b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
36375961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
363816ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:cHRM                 ",msg,
363916ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36405961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3641cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3642cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
36435961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
36443b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
36455961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
364616ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:bKGD                 ",msg,
364716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36485961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
36495961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
36503b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%s",
36515961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3652cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
365398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#if defined(PNG_iCCP_SUPPORTED)
365498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_iCCP != MagickFalse)
365516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageProperty(image,"png:iCCP                 ",msg,
365616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
365798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#endif
3658cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36594eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
366016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageProperty(image,"png:tRNS                 ",msg,
366116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36624eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36634eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
366498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_sRGB != MagickFalse)
36654eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
36663b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
366798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            "intent=%d (%s)",
366898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            (int) intent,
366998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            Magick_RenderingIntentString_from_PNG_RenderingIntent(intent));
367016ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:sRGB                 ",msg,
367198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp                 exception);
36724eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
36734eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
36744eb3931feb349dd87142c78503b779228f3e1a0fglennrp
367598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_gAMA != MagickFalse)
36764eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
36773b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
367816ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
367916ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
368016ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:gAMA                 ",msg,
368116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36824eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3683cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36844eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3685cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
36864eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
36873b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
368807523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
36894eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
369016ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:pHYs                 ",msg,
369116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
36924eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
36934eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3694cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
36954eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
36964eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
36974eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
36983b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
36994eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
370016ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:oFFs                 ",msg,
370116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
37024eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
37034eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
37044eb3931feb349dd87142c78503b779228f3e1a0fglennrp
370507523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
370607523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
370707523c7d2e40370804c2036295571e4b6426f94dglennrp       {
37083b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
370907523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
371007523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
371116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:vpAg                 ",msg,
371216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
371307523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3714cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3715cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3721cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
37260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3727edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
3728edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
3729edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
3730edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3731edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* }  for navigation to beginning of SETJMP-protected block, revert to
3732edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    Throwing an Exception when an error occurs.
3733edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
3734edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
374721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
374821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
376547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
376947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3772fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
377316ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
377647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
377947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
378447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3785dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
378747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
379273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
379347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
379647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
380747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
38140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
38180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
38220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
382547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
382747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
38330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
383647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
383772715f5c299a6482f8eb175070b056d77b74a43fcristy  if ((IssRGBColorspace(image->colorspace) != MagickFalse) &&
383872715f5c299a6482f8eb175070b056d77b74a43fcristy      (image->gamma == 1.0))
383972715f5c299a6482f8eb175070b056d77b74a43fcristy    SetImageColorspace(image,RGBColorspace,exception);
384072715f5c299a6482f8eb175070b056d77b74a43fcristy
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
384316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(image,TrueColorType,exception);
38448a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
384816ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) SetImageType(image,TrueColorMatteType,exception);
38490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
385197f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
385297f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
385397f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
385497f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
385597f90e23c85b9c58387880125c29d8c99126f83aglennrp
385697f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
38580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39104383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
39114383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
39124383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3913bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393316ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3936bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
394016ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3951bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3965fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
39680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
396916ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
39770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
397816ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
39790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
39820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
40100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
40130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4021e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
4022e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
402947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
40330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4037bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
40390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
404247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
404947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4057bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
4059bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
406547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
406847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
407347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4077f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
407847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4080f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
408147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
408447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
408847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
409247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
409647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
410047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
410447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
410847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
411447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
411747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
413447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
413747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
413916ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
41400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
41470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
41510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
415873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
41590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
416416ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
41650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
41760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
41800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
41830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
41920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
41950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
419803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
421547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
422247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
422547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
423447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4242bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
424403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
425947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
42790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
43098182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
43100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43198182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
43208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
43218182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
43228182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
43238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
43248182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
43258182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
43268182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
432847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4337e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4338cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
4339da7803d6b1161960bc1e7db4d9718284c116fab8cristy            image->gamma=1.000f/2.200f;
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
434947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43585eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
43595eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
43600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
436747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
437816ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
437916ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
438316ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
438416ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4395fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
44080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
443116ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
443747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
44410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44423b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
44440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
44470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
44610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
44640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4465bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
446716ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
446916ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
447016ea139d53d867211d3bb0fa859a83de653f687ecristy    {
447116ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
447216ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
447316ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
447416ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
447516ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
447616ea139d53d867211d3bb0fa859a83de653f687ecristy    }
447747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
44810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
44830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
449403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
44980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
45000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
450316ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45053b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
45090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4511bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
451416ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
451647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45178a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             if (image->alpha_trait == BlendPixelTrait)
451816ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
451916ea139d53d867211d3bb0fa859a83de653f687ecristy               {
452016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
452116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
452216ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
452316ea139d53d867211d3bb0fa859a83de653f687ecristy               }
45240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
452616ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
452816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
452916ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
45308a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->alpha_trait=BlendPixelTrait;
453116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
453216ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
45340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
454647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
454747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
45530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
45550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
45560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
45570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
45580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
45590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
45610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
45620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
45630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
45640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
45650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
45670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
45680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
45690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
45700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
45740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
45780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
462021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
462121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4641fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
464216ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
46450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
46510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
465247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
465347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
465547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46563b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
46580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
465947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
466047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
466273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
46630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
46660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
466747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
466847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
46760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
46840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
46880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
469247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
46980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
47040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47184383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
471921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
472021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
47214383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4728bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
474616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4759bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
478538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
478638ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
478738ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4788bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
481047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
481147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4817fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
481816ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
48210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
48240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
482847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
482947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
483047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
483173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
48320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
48350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
483647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
483747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
484747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
485147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
485247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4855bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4856bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
486047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4903e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4904e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
49080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
49110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
49140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
491847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
492147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4922bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
492447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
49340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
493616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
49380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
49450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
494716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
49490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
495447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
49590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
49660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4972bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
49740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4975bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
49770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4981e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4983e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
49878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
49880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
49910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
49950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
49980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
50028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
50060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
50090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
50120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
501716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
501947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
502016ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
50210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
50240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
50320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50333b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy            (void) FormatLocaleString(page_geometry,MaxTextExtent,
5034e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
5035f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
50360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
5038bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
5040bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
50420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
50450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
50580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50618182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
50628182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
50630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
50660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
50750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5077e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
50780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5080e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
508916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
50920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
50940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
509616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
50990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
5103edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  Instead of using a warning we should allocate a larger
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
510616ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
511516ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
51230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
51260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
51330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
51340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
51360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
51370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5141e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
5142f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
51430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5145e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
5146f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
51560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
51630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
51680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
51710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
51740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
51860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
51890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
51940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
51970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
52000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
520116ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
521247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
521547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
521647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
52220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5223bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
52290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
523035ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
52390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
52450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
524947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5255bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
526212560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5270bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52738182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
52800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
528747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
528847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
52928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
52938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
52958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
52978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
52998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
53018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
53038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
530847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
531247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5320e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5321cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
532647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
533047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5333fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
534047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
534347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
534716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
53500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
53530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
535747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
53610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
53650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
536847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
536947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
537147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5372bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
537447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
537647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5377bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
538847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
53928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
53930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
53958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
53960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5397bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5398bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
53990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
54020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
54040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5407e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
540947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5412bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5413bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
54140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5415bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5416bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
54170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5418bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5419bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
54200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
54230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
54250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5428e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
543047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
54360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5440e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5441e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
544247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
54500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
54530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5454bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5462e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5463e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
54640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
546847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
546916ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
547116ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
547247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
547947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
54840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
54940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
55028a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                image->alpha_trait=UndefinedPixelTrait;
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
550416ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
55050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5509e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5510e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
552747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
553947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
556347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
556447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5573bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5576bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
558847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5591bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
559547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
559647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
561647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5623bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
562647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
562747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
56288182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
56290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5632e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5633e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
56340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
56370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
564847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
565247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
566447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
56710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5675e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5676f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
567747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
56820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
568747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
570547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
570947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
571316ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
571647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
571947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
57360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
57390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
57420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
574916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
575347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
575947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
576547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
576847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
577447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
577747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
578347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
578647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
579247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
579547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
580147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
580447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
581047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
581347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
581947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
582347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
582716ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
583147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
585047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
585416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
585747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
586047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
586416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
586747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
587047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
587547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
58918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
58938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
589747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
590416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
590647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
591247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
591416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
591747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5920bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5922bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
593047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
593347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
593647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
593947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
594247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
594547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
594847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
595647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
595947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
596247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
596747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
597747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
598447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
598747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
599347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
600147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
60038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
6016bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
6018bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
602016ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
602516ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
602647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
603347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
603747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
604447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
604747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
604847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
604947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
605816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6061e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
6062e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
607316ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
607816ea139d53d867211d3bb0fa859a83de653f687ecristy              AcquireNextImage(image_info,image,exception);
607947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
608647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
60890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
60910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
610147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
61108a46d827a124555f0c48fb2368ec1bba8e079ab6cristy            image->alpha_trait=UndefinedPixelTrait;
611116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
61120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6116e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6117e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
612147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
612216ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
612716ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
612847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
613547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
61410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
61440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
61530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
61620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
616847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
617247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
617747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6178bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
617947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
619147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
620447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
623747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
624047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
624247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
624347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
624547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62484e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
624947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
625247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
625547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
625747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
625847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
626047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
626447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
626747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
626947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
627047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
627247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62754e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
627647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
627947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
628247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
628447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
628547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
628747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
629716ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
629816ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
629916ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
630016ea139d53d867211d3bb0fa859a83de653f687ecristy
630116ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
630216ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
630316ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
630416ea139d53d867211d3bb0fa859a83de653f687ecristy
6305bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
630916ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
631316ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
631416ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
631647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
631747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
632147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
632216ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
632347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63393faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6347bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
635147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
635416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
635516ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
635616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
635716ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
635816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
635916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
636016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
636116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
636216ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
636447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63738a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                if (image->alpha_trait == BlendPixelTrait)
637416ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
637547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
637816ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
637916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
638047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
638347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
638647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
638947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6398e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6399bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
640116ea139d53d867211d3bb0fa859a83de653f687ecristy                length=(size_t) image->columns*GetPixelChannels(image);
640216ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
640316ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
640447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
640516ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
640616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
641347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
641647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6417bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6420bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
642147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6422bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6423bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
642447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6425bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6426bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
642747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6428bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
643047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6432bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
643347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
643747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6438bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
644447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
644716ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6450bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
64549fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
645516ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
645616ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
645747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6458bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6460fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6469bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
647016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
647116ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
647216ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
647316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
647416ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
647516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
647616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
647847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6482bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
648316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
648416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
648516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
648616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
648716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
648816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
648916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
649016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6491bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
649247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
649616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
649716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
649816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6499bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
650016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
650116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
650216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
650316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6504bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
650516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
650616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
650716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
650816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6509bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
651016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
651147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65128a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                              if (image->alpha_trait == BlendPixelTrait)
651316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
651416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
651516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6516bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
651716ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
651947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
652416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
652516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
652716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
652816ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
653147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6536bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
653716ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
653816ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
653916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
654016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
654116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
654216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
654316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
654416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6545bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
654647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6548bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
654916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
655016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
655116ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
655216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
655316ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
655416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
655516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6556bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
655747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
656016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
656116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
656216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6563bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
656416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
656716ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
656816ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
656916ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
657147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
657447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
657747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
657816ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
657916ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6596e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6598bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
660016ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
660416ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
660516ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
660647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6607bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
661016ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
66117c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6612bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6613bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
661447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6615bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6616bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
661747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6618bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6619bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
662047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6621bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
662347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6625bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
662647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
663216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
663316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
663416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
663516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
663747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6641bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
664216ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
664316ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
664416ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
664516ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6646bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
664747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
664816ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
665216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
665316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
665416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6655bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
665616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6657bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
665816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
665916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
666016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6661bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
666216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6663bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
666416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
666516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
666616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6667bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
666816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
66698a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                              if (image->alpha_trait == BlendPixelTrait)
667016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
667116ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
667216ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6673bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
667416ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
667647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6681bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
668216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
668316ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6684bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6686bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
668716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
668816ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6689bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
669247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6697bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
669816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
669916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
670016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
670116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6702bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
670347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6705bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
670616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
670716ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
670816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
670916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6710bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
671147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
671516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
671616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
671716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6718bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
671916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
672216ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
672416ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
672516ea139d53d867211d3bb0fa859a83de653f687ecristy                    p+=GetPixelChannels(image);
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
672747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
67313faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6737bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
674047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6741bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
674316ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
674416ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
674516ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
674616ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
674716ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
674816ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
674916ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
675016ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
675116ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
675347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
678747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6804bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
681047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
682247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
683316ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68452b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
68462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
684716ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
68482b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
68492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
68502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
68512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
68522b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
68533faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
6854cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
6855cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
6856cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
6857cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
6858cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
6859cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
686016ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
68618640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6863d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6867bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6870d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6874d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
687647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
687847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
688247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
68930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
689416ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
689916ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
690447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
690847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
69208a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
69210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
692316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
69240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
69290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
69320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
694047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
694116ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
694447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
69490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
695447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
695516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
696047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
696847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
696916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
697347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
697947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
698016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
698247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
698547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
69930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
69960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
69990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
700447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
70100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
70120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7015e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
7016e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
70170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
702547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
702847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7030e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
703147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7036e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7048bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
705347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
705516ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
705647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
705947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
706247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
70703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
707147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
707447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
709147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
710147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
710447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7106e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
7107e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
710847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7110f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7111f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
711247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7113f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7114e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7115e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7116f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7117f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
711847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
712247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
712547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
712825c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
713347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
713647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
713947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
714425c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7167bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7170bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
718347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
718947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
719747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
720147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
720947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
721247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
721747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
722047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
722347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
722947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
723447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
723947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
724247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
724747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
725247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
726247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
726647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
727347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
727647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
728147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
728947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
729447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
730247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
730947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
731647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7317edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
7318cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
731918b17443128598500357da7bff2f01683cf32890cristy#endif
732047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
735147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7352edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
7353cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
7354cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
735925c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
737816ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
737916ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
738716ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7437cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7444bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
74650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
74660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
74680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7469a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
7470a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
7471a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7472a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
7473a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
7477a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
7478a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping,
7479a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy      (png_alloc_size_t) allocated_length);
7480a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
7481a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7482a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
7483a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
7484a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
74893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
74903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
74933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
74963b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7497f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
749947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7500bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
750747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
75093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
75103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
751447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
751747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7523cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
75244383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
753847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
753947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
754047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
754247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7546cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
754847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
754947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
755047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
755147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
755247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
755347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7554cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7555cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7556cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
755747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
755847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
755947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
756047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
756147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
756247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
756347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7564cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
756547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
756747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
757047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7574b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7575b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
757716ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
757916ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
758016ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
758116ea139d53d867211d3bb0fa859a83de653f687ecristy
758216ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
758316ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
758416ea139d53d867211d3bb0fa859a83de653f687ecristy
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7598cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7599cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7600e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7601e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
76025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
760339992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
760439992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
76075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
76085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
76095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
76175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
76185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
76195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7620bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
762458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
762521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
762658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
762758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7628da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7629fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7630d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
76318d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
763239992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7633991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7634991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7635991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
763626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
763726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
763826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7639a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7640e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
764126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
764226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
764326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
764426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
764526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
764626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
764726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7648e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
764926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
765026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
765126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
765226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
76538d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
76540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
76550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
765682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
76578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7658d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7659d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
766416ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
766516ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
766616ea139d53d867211d3bb0fa859a83de653f687ecristy
7667bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
767275fc68f33e6e766a22e8ed653c3ed50b0d142827cristy    *volatile ping_pixels;
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7675f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
76760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
76775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
76785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
76795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
76805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
76815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
76825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7683bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
76845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
76855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7687bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7692dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7693fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7694f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
76958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
76968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
76978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7698dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7699dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7700dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7701dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7702dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7703dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7705fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
770716ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
770816ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
770916ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
771016ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7711b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
77125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
77130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
77145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
77155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
77165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
77175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
77185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
77195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
77205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
77215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
77225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
77235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
77245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
77255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
77265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
77275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
77285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
77295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
77305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7731dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
7732dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
7733dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
7734dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7735da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
7736d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
77378d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
773839992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
7739991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
7740991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
7741991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
7742991d11dd9c33e65872778b81aff1347cd2878154glennrp
77430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
77440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
7745a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
7746dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
77470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
77480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
77490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
77500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
77510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
77520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
77530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7754dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
77550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
77560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
77570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
77580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
77598d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
77600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
77610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
77620d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
77630d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
77640d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
77650d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
77660d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
77670d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
77680d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   if (ping_exclude_sRGB == MagickFalse)
77690d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
77700d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
77710d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
77720d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
77730d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
77740d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
77750d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
77760d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
77770d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
77780d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
77790d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
77800d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
77810d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
77820d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
77830d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
778416ea139d53d867211d3bb0fa859a83de653f687ecristy               (LocaleCompare(name,"ICM") == 0))
778516ea139d53d867211d3bb0fa859a83de653f687ecristy              {
7786ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
7787ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   icheck;
77880d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7789ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 /* 0: not a known sRGB profile
7790ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 1: HP-Microsoft sRGB v2
7791ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 2: ICC sRGB v4 perceptual
7792ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  * 3: ICC sRGB v2 perceptual no black-compensation
7793ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                  */
77940d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 png_uint_32
7795ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   check_crc[4] = {0, 0xf29e526dUL, 0xbbef7812UL, 0x427ebb21UL},
7796ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   check_len[4] = {0, 3144, 60960, 3052};
77970d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7798ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
7799ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
7800ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   profile_crc;
780129a106ed9ec29e243521b0f2a26c14281de8347fglennrp
7802ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
7803ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
78040d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7805ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
780629a106ed9ec29e243521b0f2a26c14281de8347fglennrp
7807ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 for (icheck=3; icheck > 0; icheck--)
780829a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
7809ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   if (length == check_len[icheck])
7810ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
7811ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7812ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
7813ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
78140d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7815ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     data=GetStringInfoDatum(profile);
7816ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     profile_crc=crc32(0,data,length);
78170d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
7818ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7819e54cd4b9aa386137b617b4b7fc66436c70466007glennrp                         "      with crc=%8x",(unsigned int) profile_crc);
7820ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
7821ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     if (profile_crc == check_crc[icheck])
7822ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
7823ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7824ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                            "      It is sRGB.");
7825ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
7826ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                          image->rendering_intent=PerceptualIntent;
7827ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
7828ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
782929a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
78300d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
7831ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 if (icheck == 0)
783229a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7833ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        "    Got a %lu-byte ICC profile",
783429a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
783529a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
78360d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
78370d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
78380d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
78390d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
78400d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
78418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
78428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
78438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
78448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7845fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
7846fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7847fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
7848fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7849fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
7850fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
7851fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7852fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
7853fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
7854fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7855fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
7856fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
785728af3713c9111a471cc868c787760de89236fa3cglennrp
7858750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  if (image->storage_class == PseudoClass &&
78597e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
78607e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png_colortype != 0 &&
78617e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     mng_info->write_png_colortype != 4)))
78627e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
786316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
78647e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
78657e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
78667e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
7867c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
786828af3713c9111a471cc868c787760de89236fa3cglennrp    {
7869c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
7870c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
7871c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
7872c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
7873c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7874c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
7875e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
7876c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
7877c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
787828af3713c9111a471cc868c787760de89236fa3cglennrp    }
7879bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
78803d9f5ba107b160e1819bb6baeeb3a9f521e9f450cristy  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
788116ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
78820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78833241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
78843241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
78853241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
78863241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
78873241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
788816ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
78893241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7890a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
7891a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
7892a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
7893a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
7894a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7895a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
7896a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7897a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
7898a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
7899a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
7900a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
79018e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
790267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < MAGICKCORE_QUANTUM_DEPTH)
790367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
790416ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
79058e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
79068e58efdecda887b08ef730d68290a61081ef2566glennrp
79078e58efdecda887b08ef730d68290a61081ef2566glennrp       if (image->depth > 8)
79088e58efdecda887b08ef730d68290a61081ef2566glennrp         {
79098e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 16
79108e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 16-bit */
791191d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR16PacketRGBO(image->background_color);
79128e58efdecda887b08ef730d68290a61081ef2566glennrp
79138e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
79148e58efdecda887b08ef730d68290a61081ef2566glennrp           {
791516ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79168e58efdecda887b08ef730d68290a61081ef2566glennrp
791716ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79188e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79198e58efdecda887b08ef730d68290a61081ef2566glennrp
79208e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
79218e58efdecda887b08ef730d68290a61081ef2566glennrp             {
792216ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR16PixelRGBA(r);
792316ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
79248e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7925bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
79268e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
79278e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
79288e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79298e58efdecda887b08ef730d68290a61081ef2566glennrp
79308e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
79318e58efdecda887b08ef730d68290a61081ef2566glennrp           {
79323e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
79338e58efdecda887b08ef730d68290a61081ef2566glennrp             {
793491d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR16PacketRGBO(image->colormap[i]);
79358e58efdecda887b08ef730d68290a61081ef2566glennrp             }
79368e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79378e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 16 */
79388e58efdecda887b08ef730d68290a61081ef2566glennrp         }
79398e58efdecda887b08ef730d68290a61081ef2566glennrp
79408e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 4)
79418e58efdecda887b08ef730d68290a61081ef2566glennrp         {
79428e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 8
79438e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 8-bit */
794491d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR08PacketRGBO(image->background_color);
79458e58efdecda887b08ef730d68290a61081ef2566glennrp
79468e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
79478e58efdecda887b08ef730d68290a61081ef2566glennrp           {
794816ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79498e58efdecda887b08ef730d68290a61081ef2566glennrp
795016ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79518e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79528e58efdecda887b08ef730d68290a61081ef2566glennrp
79538e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
79548e58efdecda887b08ef730d68290a61081ef2566glennrp             {
795516ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR08PixelRGBA(r);
795616ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
79578e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7958bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
79598e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
79608e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
79618e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79628e58efdecda887b08ef730d68290a61081ef2566glennrp
79638e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
79648e58efdecda887b08ef730d68290a61081ef2566glennrp           {
79653e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
79668e58efdecda887b08ef730d68290a61081ef2566glennrp             {
796791d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR08PacketRGBO(image->colormap[i]);
79688e58efdecda887b08ef730d68290a61081ef2566glennrp             }
79698e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79708e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 8 */
79718e58efdecda887b08ef730d68290a61081ef2566glennrp         }
79728e58efdecda887b08ef730d68290a61081ef2566glennrp       else
79738e58efdecda887b08ef730d68290a61081ef2566glennrp         if (image->depth > 2)
79748e58efdecda887b08ef730d68290a61081ef2566glennrp         {
79758e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
797691d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
79778e58efdecda887b08ef730d68290a61081ef2566glennrp
79788e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
79798e58efdecda887b08ef730d68290a61081ef2566glennrp           {
798016ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79818e58efdecda887b08ef730d68290a61081ef2566glennrp
798216ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
79838e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
79848e58efdecda887b08ef730d68290a61081ef2566glennrp
79858e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
79868e58efdecda887b08ef730d68290a61081ef2566glennrp             {
798716ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
798816ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
79898e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7990bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
79918e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
79928e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
79938e58efdecda887b08ef730d68290a61081ef2566glennrp           }
79948e58efdecda887b08ef730d68290a61081ef2566glennrp
79958e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
79968e58efdecda887b08ef730d68290a61081ef2566glennrp           {
79973e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
79988e58efdecda887b08ef730d68290a61081ef2566glennrp             {
799991d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
80008e58efdecda887b08ef730d68290a61081ef2566glennrp             }
80018e58efdecda887b08ef730d68290a61081ef2566glennrp           }
80028e58efdecda887b08ef730d68290a61081ef2566glennrp         }
80038e58efdecda887b08ef730d68290a61081ef2566glennrp
80048e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
80058e58efdecda887b08ef730d68290a61081ef2566glennrp         {
80068e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
800791d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
80088e58efdecda887b08ef730d68290a61081ef2566glennrp
80098e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
80108e58efdecda887b08ef730d68290a61081ef2566glennrp           {
801116ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
80128e58efdecda887b08ef730d68290a61081ef2566glennrp
801316ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
80148e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
80158e58efdecda887b08ef730d68290a61081ef2566glennrp
80168e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
80178e58efdecda887b08ef730d68290a61081ef2566glennrp             {
801816ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
801916ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
80208e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8021bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
80228e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
80238e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
80248e58efdecda887b08ef730d68290a61081ef2566glennrp           }
80258e58efdecda887b08ef730d68290a61081ef2566glennrp
80268e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
80278e58efdecda887b08ef730d68290a61081ef2566glennrp           {
80283e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
80298e58efdecda887b08ef730d68290a61081ef2566glennrp             {
803091d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
80318e58efdecda887b08ef730d68290a61081ef2566glennrp             }
80328e58efdecda887b08ef730d68290a61081ef2566glennrp           }
80338e58efdecda887b08ef730d68290a61081ef2566glennrp         }
80348e58efdecda887b08ef730d68290a61081ef2566glennrp       else
80358e58efdecda887b08ef730d68290a61081ef2566glennrp         {
80368e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
803791d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
80388e58efdecda887b08ef730d68290a61081ef2566glennrp
80398e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
80408e58efdecda887b08ef730d68290a61081ef2566glennrp           {
804116ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
80428e58efdecda887b08ef730d68290a61081ef2566glennrp
804316ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
80448e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
80458e58efdecda887b08ef730d68290a61081ef2566glennrp
80468e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
80478e58efdecda887b08ef730d68290a61081ef2566glennrp             {
804816ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
804916ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
80508e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8051bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
80528e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
80538e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
80548e58efdecda887b08ef730d68290a61081ef2566glennrp           }
80558e58efdecda887b08ef730d68290a61081ef2566glennrp
80568e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
80578e58efdecda887b08ef730d68290a61081ef2566glennrp           {
80583e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
80598e58efdecda887b08ef730d68290a61081ef2566glennrp             {
806091d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
80618e58efdecda887b08ef730d68290a61081ef2566glennrp             }
80628e58efdecda887b08ef730d68290a61081ef2566glennrp           }
80638e58efdecda887b08ef730d68290a61081ef2566glennrp         }
8064cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
8065cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
806667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
806767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
806870e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
8069a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
80702b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
80712b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
80722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
80732b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
80748e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
80752b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
80762b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
80772b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
80783faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
8079cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
8080cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
8081cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
8082cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
8083cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
8084cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
8085c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
808616ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
80878640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
80888640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
80898640fb5e9b1094f35f8beab436f81661b8a99448glennrp
8090c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp  /* Normally we run this just once, but in the case of writing PNG8
8091e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
8092e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
80938ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
80948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
80958ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
80968ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
8097c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
809882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
80998ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
810082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
8101d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
810282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
81038ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
8104d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
8105d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp    /* BUILD_PALETTE
8106d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8107d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
8108d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
8109d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8110d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
8111d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
8112d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
8113d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8114d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8115d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
81168a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     * If image->alpha_trait is MagickFalse, we ignore the alpha channel
8117d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8118d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8119d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8120d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8121d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8122d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8123d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8124d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8125d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
81263c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8127d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8128d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
81298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
813016ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8131d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8132d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8133d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
81348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
813516ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
813616ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8137d6bf1617e99df0272b231855a933a74e99b6578fglennrp
813816ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
813916ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8140fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8141fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8142d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8143d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8144d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8145d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8146d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8147d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8148d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8149d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8150d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8151d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8152d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81538a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             "      image->alpha_trait=%.20g",(double) image->alpha_trait);
815403812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8155d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
81563c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8157fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
81587ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
81597ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8160d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
81618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
816216ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
81632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8164d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
81657ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8166d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8169d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8170d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8171d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
817216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
81737ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
81742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8175d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8176d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8177d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8178d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8179d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8180d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8181d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8182d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8183d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8184d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
818516ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8186d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8187d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8188d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
81892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8190d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8191d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
819283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8193d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
819416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
819516ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
81967ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
81978d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
81988d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81998d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8200d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
82017ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8202d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8203fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8204fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8205fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
82062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8207d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8208d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8209d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82107ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
821116ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8212d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
821397fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8214d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8215d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
82168a46d827a124555f0c48fb2368ec1bba8e079ab6cristy           if (image->alpha_trait != BlendPixelTrait ||
821716ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
82188d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8219d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
82208d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8221d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8222d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
822316ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
822416ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8225d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8226d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8227d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8228d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8229d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
823016ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, opaque+i))
8231d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8232d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8233d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
823416ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8235d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8236d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
823716ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
823816ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8239d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
82408d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
82418d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
824216ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
82438d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8244d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
82458d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8246d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8247d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
824816ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
824916ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
825016ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
825116ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
825216ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
825316ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
825416ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
825516ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
8256972d1c4895c4ee6da1b6745e1bb9cb71ee5d6d08cristy                         GetPixelGray(image,q);
8257d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8259d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8260d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8261d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
826216ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, transparent+i))
8263d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8264d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8265d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8266d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8267d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8268d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8269d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
827016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8271d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
82728d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
82738d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8274d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8275d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8276d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8277d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8278d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8279d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
828016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8281d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8282d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
82838d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8284d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8285d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
828616ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
828716ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
828816ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8289d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8290d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8291d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8292d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8293d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8294d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8295d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
829616ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8297d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8298d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
82998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
830016ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8301d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8302d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
83033c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
83044054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
83054054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8306d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8307d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8308d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8309d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8310c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8311c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8312c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8313c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8314c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8315c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8316c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8317c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8318d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8319d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8320ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8321ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8322ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8323ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8324d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8325d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
832603812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
83278e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8328c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8329388a8c871db8f82488f34c4f41fc64a58b8cfbf7glennrp               number_opaque++;
8330c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8331c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8332c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8333c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8334c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8335c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
833603812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8337a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8338a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8339a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
83412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8342d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
83433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8344a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
8345a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
8346a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
8347a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
8348a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
8349a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
8350a080bc32a4a8b2ffec83fd836a28753959175363glennrp
8351d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8352d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8353d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8354d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8355d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
83563241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8357d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8358d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8359d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8360d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
83613241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
83628d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
83638d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
83648d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8365fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8366d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8367d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
83680fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         ping_have_non_bw=MagickFalse;
83690fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
83703d9f5ba107b160e1819bb6baeeb3a9f521e9f450cristy         if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
83710fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
83727fb2652ba366fc984d1dbb0c66560b91c57dab78cristy           ping_have_color=MagickTrue;
83730fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp           ping_have_non_bw=MagickFalse;
83740fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
83750fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
837680ebb4df61f1272808ddecfb9b79219e9dfd5e56glennrp         if (IssRGBColorspace(image->colorspace) != MagickFalse)
83770fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
837880ebb4df61f1272808ddecfb9b79219e9dfd5e56glennrp           ping_have_color=MagickTrue;
83790fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp           ping_have_non_bw=MagickTrue;
83800fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
83813241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8382d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8383d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8384d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8385d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8386d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83876185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
838816ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8389d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
83906185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8391e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8392e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8393e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
839416ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
839516ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8396e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8397e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8398e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8399e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8400e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
840116ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8402e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8403e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8404e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8405e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8406e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8408d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
84106185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
84156185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
841616ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
841716ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8420e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
842216ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8423d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8424e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8426bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8427bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
84284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
843116ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8433bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8435d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8437d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8439d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8441d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8443d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
84453241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8447d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
84483241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8453d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8454d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8455c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8456c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8457bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8473d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8474d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8478d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8479d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
84803241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
84886185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8489d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8492d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
84932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8495d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8499d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
850016ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
85023faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
85033faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8504d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8505d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8506d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8507d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8510d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8511d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8512d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8513bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8514d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8515d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8516d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8517d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8518fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8519fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8520d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8521d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
852216ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
85233c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
852416ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
85263c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8527d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8528d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
853003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
85318a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                  if ((image->alpha_trait != BlendPixelTrait ||
853216ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
853316ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
853416ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
853516ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
85366185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
853716ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8538d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
85396185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
854003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
854116ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8542d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8545d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8547d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8548d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8549d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8550d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8552d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8554d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8555d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8556d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
855816ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
855983c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8561d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
856272988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8565d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8566d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8567d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8568d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8569d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
857016ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8571d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
85726185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
85736185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
85743c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8576d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8577d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8578d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8579d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
85803c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8581d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8582d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
85833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8585d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8586d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8587d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
858803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8589d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8590d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
85926185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8593d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8594d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8595d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8596d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
85976185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8598d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8599d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8600d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8601a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8602d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8603d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8604d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8605a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8606d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8607d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8608d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8609d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8610d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8611d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8612d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
86136185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
861403812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
861503812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8616d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86173c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8618c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8619c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8620fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8621c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8622c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8623c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8624c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8625c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8626c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8627fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8628c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8629130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8630130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8631130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8632c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8633130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8634c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8635c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8636c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8637fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8638c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8639c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
864016ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8641fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
864216ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8643c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8644fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8645c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8646c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
864716ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
86488ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
864916ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelInfoPixel(image,&image->background_color,r);
865016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
86518ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
86528ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
865316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
865416ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8655c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8656bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8657c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8658c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8659fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8660c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8661c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8662c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
866316ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
866416ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
866516ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
8666c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8667c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8668c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8669c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8670c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8671e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8672e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8673e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8674c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8675d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8676d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8677d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8678d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8679d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8680d337164012450d70d62e71cf4a308a29004f7d57glennrp
8681d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8682d337164012450d70d62e71cf4a308a29004f7d57glennrp
868391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8684d337164012450d70d62e71cf4a308a29004f7d57glennrp
8685d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8686d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8687d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8688d337164012450d70d62e71cf4a308a29004f7d57glennrp
8689d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8690d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8691d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8692d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
869316ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8694d337164012450d70d62e71cf4a308a29004f7d57glennrp
869516ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8696d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
8697d337164012450d70d62e71cf4a308a29004f7d57glennrp
8698d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
8699d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
870016ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
870154cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
870216ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8703d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
8704bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8705d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8706d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
8707d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8708d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8709d337164012450d70d62e71cf4a308a29004f7d57glennrp
8710d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
8711d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
8712d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8713d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
8714d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8715d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
87168e58efdecda887b08ef730d68290a61081ef2566glennrp
8717d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
8718d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
871991d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
8720d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8721d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8722d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
8723d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
8724d337164012450d70d62e71cf4a308a29004f7d57glennrp
872582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
872682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
872782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
872882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
872982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
873082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
873182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
873282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
873391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
873482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
873582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
873682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8737e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
873882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
873982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
874082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
874182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
874282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
874316ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
874482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
874516ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
874682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
874782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
874882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
874982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
875016ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
875116ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
875216ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
875382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
8754bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
875582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
875682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
875782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
875882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
875982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
876082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
876182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
876282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
876382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
876482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8765e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
876682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
876782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
876891d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
876982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
8770d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8771d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
877282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
8773c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
87748ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
8775c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8776c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
8777c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8778c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
8779c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
87808ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
87818ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
87823faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
87833faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
87843faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
87853faa9a3fb01696daaf976d595f492cb530bffb21glennrp
878691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
8787fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8788c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
8789c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8790e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
8791fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8792c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
8793c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8794c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
8795c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
879616ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
87978d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
879816ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8799c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
8800c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8801c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
8802c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
880316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
880454cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
880516ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8806c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
8807bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8808c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8809c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
8810c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8811c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8812c722dd852e8abe407c2846d39662f7ade9c234deglennrp
8813c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
8814c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
8815c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8816c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
8817c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8818e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
8819c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
8820c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
882191d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
8822c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8823c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
8824c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8825c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8826c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
88278ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
88288ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
88298ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
88308ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      /* Take care of special case with 256 colors + 1 transparent
88318ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
88328ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
88338ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
88348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
88358ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
88368ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
88378ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
88388ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
88398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
88408ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
8841bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
88428ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
88438ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
88448ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
88458ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
884616ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8847bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
884816ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
88498ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
8850bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
88518ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
88528ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
885316ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
885416ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
885516ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
885616ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
88578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
885816ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
88598ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
886016ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
88618ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
8862bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
88638ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
88648ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
8865bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
88668ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
88678ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
88688ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
88698ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
88708ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
88718ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
88728ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
88738ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
88748ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
88758ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
88768ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
88778ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
88788ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
88798ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
88808ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
88818ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
8882fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
8883fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
8884fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8885fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
8886fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
8887fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
8888fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
88890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
88900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
88910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
8892d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
88930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
88940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
88950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
88960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
88970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
88980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
88990e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
89008d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
8901d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
89020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
89030b206f5daa453dc1035db5890cabc899736dc2d0glennrp
89040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
89050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
8906fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
8907fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
8908fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
89095a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
89105a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
89115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
8912fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
89135a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
89145a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
8915fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8916fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
8917fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8918fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
8919fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
8920fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8921fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
8922fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
8923fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
892416ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
8925fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
8926fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8927fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
8928fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
8929fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
8930fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
893116ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
8932fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
8933fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8934fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
8935fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
893616ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
893716ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
893816ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
893916ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
894016ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
894116ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
894216ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
8943fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
8944fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8945fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8946fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
8947fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
894816ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
8949fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
8950bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8951fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
8952fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
8953fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
8954fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8955fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
8956fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
895767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
895867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
895967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
8960fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
896167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
896267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
896367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
896467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
8965fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
896667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
896767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
8968fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
8969fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8970bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8971fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
8972fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8973fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
8974fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8975fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
8976fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8977fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
8978fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8979fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
8980fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8981fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
8982fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
8983fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
8984fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
89853c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
89863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
89873c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
89883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
8989f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
8990b0a657e13c4aefba39c51292005427b47277869dcristy  image_matte=image->alpha_trait == BlendPixelTrait ? MagickTrue : MagickFalse;
899183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
89920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
89931273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
899552a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
899652a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
899752a479ca718756af72f96e127f8256499ab68f76glennrp    {
899816ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
899916ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
900016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
900115e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
900216ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
900352a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
900452a479ca718756af72f96e127f8256499ab68f76glennrp    }
900552a479ca718756af72f96e127f8256499ab68f76glennrp
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
901016ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
901116ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
901216ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
9013cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
9014cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
90150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
901716ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
9018cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
90190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
90230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
90250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
9033cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
9045edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
9046cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9048edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9049edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (ping_pixels != (unsigned char *) NULL)
9050edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
9051edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9052edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (quantum_info != (QuantumInfo *) NULL)
9053edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        quantum_info=DestroyQuantumInfo(quantum_info);
9054edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
905516ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
905616ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
905716ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
905816ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9061edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9062edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
9063edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
9064edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
9065edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
9066edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9067edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
9068edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
9069edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
9070edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90749bf97b6c2143eb20c330346b01e82102cc082725glennrp
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
907725024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  {
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
907925024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
908025024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     /* Disable new libpng-1.5.10 feature when writing a MNG because
908125024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      * zero-length PLTE is OK
908225024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      */
908325024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     png_set_check_for_invalid_index (ping, 0);
908425024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# endif
908525024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  }
90862b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
90912b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90942b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
90962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90974e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
90984e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
90992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
91020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
91050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
91090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
91120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
91150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9119e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9121e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91238a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        "    image_matte=%.20g",(double) image->alpha_trait);
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91258640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91278640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91298640fb5e9b1094f35f8beab436f81661b8a99448glennrp
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
91315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
9132dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
913326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
913526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
913626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
913716ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
9141dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9142dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9146dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
9147823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
914816ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
9149823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
915016ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9152dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9155dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
915616ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
915716ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9159991d11dd9c33e65872778b81aff1347cd2878154glennrp
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9162dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
916316ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
916416ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9166991d11dd9c33e65872778b81aff1347cd2878154glennrp
9167823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9168823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9169823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9170823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9171823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9172991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
917426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9176a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
917726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
917826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9179a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9181a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9182a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9183a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9184a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9185a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9186a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
91870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9188a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9189a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
91900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9191a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9192a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
91930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9194a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9195a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
91960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9197a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9198a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
91990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9200a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9201a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
92020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9203a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9204a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9205c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9206c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
92070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
92080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
92103b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
92113b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92123b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9213c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9214c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9215c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
92163b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
92173b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92183b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
92193b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
92200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
922226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
92283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
92290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92301273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9233fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
92340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
92350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
92378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
92388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
92390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
92410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
92420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
92430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
92440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
92460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9248f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
92490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
92510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
92520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
92530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
92540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
92550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
92560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
925767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
92580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
925967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
926067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
926167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
92620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
92652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
92668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
92678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
92688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
92695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
927058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
92718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
92720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
92730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
92740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
92750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
92768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
92798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
92800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92822cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
92838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
92840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
92860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
92870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
92898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
92908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
92910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92921273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
92934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
92941273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
92951273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
92961273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
92971273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
92984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
92994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
93004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
93010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9303c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9304c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9305c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9306c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9307c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9308c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9309c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
93104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
93120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93137e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  else if (mng_info->write_png24 || mng_info->write_png_colortype == 3)
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
93165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93197e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  else if (mng_info->write_png32 || mng_info->write_png_colortype == 7)
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
93225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
93280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
93315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
93320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
93345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
93362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
93378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
93388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
93397c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
93407c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
93417c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93427c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
93440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93457c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93493c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
93500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9351d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
93528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
93530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9354d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
93565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
93590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9360d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
93625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
93650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93665aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
93675aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
93685aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
93695aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
93707c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
93717c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
93727c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
93745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
93758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
93765aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
93775aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
93785aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
93795aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
93805aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
93810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93820b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
93835aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
93845aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
93855aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
93865aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
93878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
93885aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
93895aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
93905aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
93915aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
93925aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
93935aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
93945aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
93958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
93960b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
93975aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
93985aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
93995aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
94005aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
94015aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
94020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
94035aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
94050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
940726c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94088640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
940926c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
94105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
94110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
94120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
94130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
94140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
94150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
94160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9418d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9419d6bf1617e99df0272b231855a933a74e99b6578fglennrp
94205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
94228a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (image->alpha_trait != BlendPixelTrait && ping_have_non_bw == MagickFalse)
94238d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
94258640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
942835ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
94295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
94300f111984738842d27d04aed2a3f823d82a943506glennrp
94310f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
94320f111984738842d27d04aed2a3f823d82a943506glennrp           {
94330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9434edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"image has 0 colors");
94350f111984738842d27d04aed2a3f823d82a943506glennrp           }
94360f111984738842d27d04aed2a3f823d82a943506glennrp
943735ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
94385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9439d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9441d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9442d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9443d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9444d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
94450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9446d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9447d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9448d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
94490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9450d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9451d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
94545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
94552b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94591a56e9c9268976936eeab9fe97eb664b847e444cglennrp        "    Tentative PNG color type: %s (%.20g)",
94601a56e9c9268976936eeab9fe97eb664b847e444cglennrp        PngColorTypeToString(ping_color_type),
94611a56e9c9268976936eeab9fe97eb664b847e444cglennrp        (double) ping_color_type);
94620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9464e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
94650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9467e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
94680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94703c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
94718640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
94728640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94738640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9474e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
947758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
94804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
94817c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
94827c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
94837c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
94842b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94857c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
94867c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
94877c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
94882b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
94904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
94924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
94934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
94944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
94954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
94964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9497a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
94984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
94997c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
95007c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
95017c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
95024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
95030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
95054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
95064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9507bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
95100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
95124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
95130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
95154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
95160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
95184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
95190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
95214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
95220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
95244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
95250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
95274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
95280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
95304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
95310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
953316ea139d53d867211d3bb0fa859a83de653f687ecristy                (ScaleQuantumToShort(GetPixelInfoIntensity(
95344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
95350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
95370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
95394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
95400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
95424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
95434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9544fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9545fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9546fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9547fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9548fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
95494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
95502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
95524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
95537c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
95547c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
95550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
95574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
95584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
95594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
95604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
95614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
95624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
95634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
95644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
95654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
95664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
95673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
95695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
95705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
95715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
95725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
95733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
95743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
95753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95768640fb5e9b1094f35f8beab436f81661b8a99448glennrp
95773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
95780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95792e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
95803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
95810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
958239992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
95833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
95848d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
95858d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
95863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
958735ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
95880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
95909c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
95910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95927c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
95933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
95954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
95963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
95974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
95984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
95994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
96004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
96024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
96034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
96044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
96083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
96090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9610136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9611d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9612f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
96130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
96155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
96160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
96183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
96205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
96223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
96245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
96250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
962635ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9627bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
96285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
96312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
96320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
96330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
96363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
96371a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
96393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
96423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
96493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
96513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
96533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
96544bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
96563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
96572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
96599c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
96600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
96629c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
96630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
96659c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
96663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
96673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
96695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
96703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
96710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
96730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
96753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
967617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
967717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
96793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
96813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
96823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
96835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
96840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
968558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
96863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
96879c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
96880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96893b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
96909c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96919c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
96923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
96930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
96953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9696bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
96973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
96983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
96993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
97013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
97020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97033b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
970598156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
9706f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
97070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
970839992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
97093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
97100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
9712d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
97133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9714befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
9715befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
9716befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
97175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
9718befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
97190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
972016ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
97215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
97223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
97230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
97250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
972658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
97270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
97280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
9729d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
9730d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
97310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9733d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
9734d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
97370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
97380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9739d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
97400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
9741c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
9742c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
9743c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9744c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
9745c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
9746d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
9747d6bf1617e99df0272b231855a933a74e99b6578fglennrp
9748d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
9749d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
9750750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp                       ping_trans_alpha[i]= (png_byte)
975116ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
9752d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
97530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
97540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
97553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
97570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
97593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9760c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
97613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
97623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
97630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
97664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
97674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
97684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
97704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
97714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
97724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
97734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
97744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
97755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
97765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
97775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
97785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
97794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
97804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
97814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
97824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
97844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
97854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
97864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
97874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
97883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
97903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97914383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
97924383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
97932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
97953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
97963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
97975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
97983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
97993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
98003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
98013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
98023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
980335ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
980435ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
980535ef824baa82511126ff0072ae30eee0da9c05a3cristy
980622ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
98073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
980926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
98103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
981116ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
981216ea139d53d867211d3bb0fa859a83de653f687ecristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(
981316ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
981416ea139d53d867211d3bb0fa859a83de653f687ecristy
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
98168f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
981716ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
981816ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
981916ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
982016ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
98213b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
9822991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
982326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98253e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
98263e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98273e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
98283e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
98293e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
98309be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
98313e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
98323e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
98333e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
98343e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98353e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
98363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
983717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
983826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
983926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
98401273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
984117a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
984217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
984317a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
984417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
984517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
984617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
984717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
9848a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
9849a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
985017a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
985117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
985217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
985317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
98543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
98550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
98560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
98580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
9859a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
986013d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
9861a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
98620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
98633b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
98643b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
98650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
98660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
98680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
98690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
98700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
98710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
9872a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
987317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
9874d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
98753c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
98763b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
98773b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98783b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
98793c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
98803c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
988117a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
988226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
988317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98861a56e9c9268976936eeab9fe97eb664b847e444cglennrp      "    PNG color type: %s (%d)", PngColorTypeToString(ping_color_type),
98871a56e9c9268976936eeab9fe97eb664b847e444cglennrp      ping_color_type);
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
98903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
98930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
98950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
98980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
98990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
99010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
99050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99064054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
99074054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
990810d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
990910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
991010d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
991110d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
991210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
991310d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
991410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
991510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0: Use Z_HUFFMAN_ONLY strategy with the
991610d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
991710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
991810d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
991910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
992010d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
992110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
992210d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
992310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
992410d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
992510d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
992610d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
9927750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
992810d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
992910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
993010d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
993110d739ef54404090a55cb8977fc51f85cafa81a5glennrp             a MNG, othewise "none".  Did not work in IM-6.7.0-9
993210d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
993310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
993410d739ef54404090a55cb8977fc51f85cafa81a5glennrp        8:   Z_RLE strategy, all filters
99351868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
993610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
993710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        9:   Z_RLE strategy, no PNG filters
99381868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
993910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
994010d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
994110d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
994216ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
994316ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
994410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
994510d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
994610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
99490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99501868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
99511868258559ddf946fa73ef72dd43507b32623705glennrp    {
99521868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
99531868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
99541868258559ddf946fa73ef72dd43507b32623705glennrp    }
9955750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
99561868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9961bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
99620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99631868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
99641868258559ddf946fa73ef72dd43507b32623705glennrp    }
99650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99661868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
99671868258559ddf946fa73ef72dd43507b32623705glennrp    {
99681868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
9969a24b245fac14ef0617d691de0942697f2eb31b05glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
9970a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy=Z_RLE+1;
9971a24b245fac14ef0617d691de0942697f2eb31b05glennrp#else
9972a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
9973a24b245fac14ef0617d691de0942697f2eb31b05glennrp#endif
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99761868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
99771868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
99781868258559ddf946fa73ef72dd43507b32623705glennrp
99791868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99811868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99831868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
99841868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
99850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99861868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
99871868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99881868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
99891868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
99900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99911868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99921868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99944054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
999510d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99961868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
99974054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
99984054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
99991868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100001868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
100011868258559ddf946fa73ef72dd43507b32623705glennrp        else
100021868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100031868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
100041868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
100053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100071868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
100081868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
100090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100101868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
100111868258559ddf946fa73ef72dd43507b32623705glennrp    {
100121868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
100131868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
100141868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
100151868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
100161868258559ddf946fa73ef72dd43507b32623705glennrp      else
100171868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
100181868258559ddf946fa73ef72dd43507b32623705glennrp     }
100194054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
100201868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
100211868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
1002210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
100231868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
100241868258559ddf946fa73ef72dd43507b32623705glennrp    {
100251868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
100261868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
100271868258559ddf946fa73ef72dd43507b32623705glennrp      {
100281868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
100291868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
100301868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
100311868258559ddf946fa73ef72dd43507b32623705glennrp      }
100321868258559ddf946fa73ef72dd43507b32623705glennrp#endif
100334054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
100341868258559ddf946fa73ef72dd43507b32623705glennrp    }
100350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100361868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
100371868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
100380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100391868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
100401868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
100411868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
100420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100431868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
100441868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
100451868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
100462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
100470d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
100480d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
100490d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy     (image->rendering_intent == UndefinedIntent))
100500d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
100510d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
100520d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
100530d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
10054c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
10055c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
10056c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10058c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
100590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10060c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
10061c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
10062c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
10063c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
10064c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
1006526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
10066c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
10067c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
10068c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
1006916ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
10070e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
10071c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
10072e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
10073e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
10074e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
10075c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
10076c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
1007726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
100780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10079c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10081c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
10082c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
10083cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
10084c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
10085c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
10086c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
10087c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
10088c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
100890b206f5daa453dc1035db5890cabc899736dc2d0glennrp
10090c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
10091c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10092c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
100930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10094c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
10095c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
100960d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
100983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
101015f11bf96e873e4051dcb4682ec3b225ff46c36aeglennrp      (image->rendering_intent != UndefinedIntent))
101023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1010326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
1010426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1010526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
1010626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
1010726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
1010826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
1010926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1011026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
101110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1011226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
10113cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
10114cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
1011526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
101163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1011726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
101185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
101193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101212cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
101222cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
1012326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
1012426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
101253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
101263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
101273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
101283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
101303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
101313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
101343b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
101353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
101363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1013726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
101382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
1013926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1014126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
1014226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
1014326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
1014426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
1014526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
1014626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
1014726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
1014826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
1014926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
1015026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
1015126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
1015226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
1015326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1015426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1015526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1015626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1015726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1015826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1015926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1016026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1016126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1016226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1016326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1016426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1016526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1016626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
101673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10168dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
101695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
101703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
101723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
101733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101745d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
101753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10176d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
101798d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
101803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
101815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
101822b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
101835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
101845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
101853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
101860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
101888d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
101895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
101930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
101945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
101965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10197991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
101980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
102013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
102020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
102030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
102040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
102060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
102070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
102083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
102093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102115d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy                  "  Defined png:bit-depth=%u, Computed depth=%u",
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
102135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
102143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
102150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
102163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
102173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
102183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102195d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy                  "  Defined png:color-type=%u, Computed color type=%u",
102203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
102215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
102223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
102233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
102240e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
102253bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
102265d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy        "Cannot write image with defined png:bit-depth or png:color-type.");
102273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102298a46d827a124555f0c48fb2368ec1bba8e079ab6cristy  if (image_matte != MagickFalse && image->alpha_trait != BlendPixelTrait)
102303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
10232b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait = BlendPixelTrait;
1023316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageAlpha(image,OpaqueAlpha,exception);
102340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10235b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
10236b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10237b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
102383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102400e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10241e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
10242991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
10243c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
10244991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
10245c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
10246c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10247c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
10248c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
10249e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
10250e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
102513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
102543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
102565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
102575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
102585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
102595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
1026039992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
1026139992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
10262f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
102630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102643b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
1026539992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
102668640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
102670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
10268d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
102690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10270d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10271d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
102720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
102730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
102740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
10275d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
102760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
102770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
102780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10279d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
102800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
102810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
102820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
102830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
102840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
1028539992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
1028639992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
1028739992b4dd9b12ef752d55b8e402c069698851f72glennrp
1028826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1028926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1029026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10291c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1029226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
10293c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging)
10294c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10295c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10296c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10297c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10298c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10299c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10300c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10301c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10302c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10303c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10304c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10305c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10306c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10307c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1030826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10309991d11dd9c33e65872778b81aff1347cd2878154glennrp
1031026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10311dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1031226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1031326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1031426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1031526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1031626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1031726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10318823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
10319823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
10320823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10321823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10322823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10323823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10324823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10325823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10326823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10327823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10328823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10329823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10330823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10331823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10332823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1033326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10334dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10335dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10336dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
103374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10338dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1033926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1034026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1034126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1034226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10343dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1034426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1034526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1034626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1034726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1034826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10349dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10350dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10351dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10352da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10353da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1035416ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10355da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10356da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10357da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10358da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10359da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10360da8f3a7bfddac2680a3069a490db541e7944edafglennrp
103613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10362991d11dd9c33e65872778b81aff1347cd2878154glennrp
1036339992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10364991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
103653b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
103660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
103670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
103690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10370991d11dd9c33e65872778b81aff1347cd2878154glennrp
103710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
103720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
103730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
103740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
103750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10376991d11dd9c33e65872778b81aff1347cd2878154glennrp
103770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
103780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
103790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
103800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
103810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
103820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
103830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103843b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
103850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
103860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10387c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
103880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
103890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
103900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
103910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
103920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
103930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10394991d11dd9c33e65872778b81aff1347cd2878154glennrp
103953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10396cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10397da8f3a7bfddac2680a3069a490db541e7944edafglennrp
103983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10399991d11dd9c33e65872778b81aff1347cd2878154glennrp
104003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10401cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
104023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1040326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
104043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
104054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
104064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1040726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1040826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1040926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1041026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1041126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1041226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1041303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1041426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1041526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1041626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1041726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1041826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1041926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
104203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
104213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
104239c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
104243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
104259c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
104263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
104273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
104283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
104303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
104323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10434b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10435b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
104367202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
104373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10438b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
104393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10440b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
104410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10442b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10443b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10444b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
104450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10446b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
104473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10448b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
104490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10450b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10451b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
104523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
104533b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
104543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
104553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10456b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10457b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
104580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10459b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10460e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
104613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10462cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
10463cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
104640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10465cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
10466edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Allocation of memory for pixels failed");
104670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
104703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10471ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10472ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10473edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation for quantum_info failed");
104743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
104753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
104763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
104778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
104783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
104798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
104808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
104813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
104828d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
104838d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
104843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
104858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1048616ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
104873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
104880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
104903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
104913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
104923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
104933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
104943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10495bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
104963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
104983b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104993b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10500a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1050116ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
105020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1050316ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
105043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
105050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
105073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1050816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1050916ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
105103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
105113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
105123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
105133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
105143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10516cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
105183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
105193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
105200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
105223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1052316ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1052416ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
105260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10528bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10529cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
105303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
105310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105323b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10533b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10534b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
105350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10536cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
105393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
105403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
105413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
105423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
105433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
105443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
105460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
105503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
1055158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
105525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
105538d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
105543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1055516ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
105568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
105570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
105593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
105608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
105623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1056316ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
105642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1056516ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
105672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
105708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1057116ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1057216ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
105732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1057516ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1057616ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
105772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
105798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
105822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10584b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
105853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10586b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
105882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1058916ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1059016ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
10591b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
105922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
105933b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10594b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
105962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10597cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
105992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
106018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
106028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
106038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
106048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
106058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
106068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
106078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
106080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1061116ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
106128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
106130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
106178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
106188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
106198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
106208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10621b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
10622862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
106232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1062416ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
106258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
106262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
106288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
106298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1063016ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1063116ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
106322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1063416ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1063516ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
106368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
106372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
106398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1064016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10641cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1064216ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
106432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
106458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
106478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
106482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1065016ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1065116ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
106522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1065416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1065516ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
106562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106573b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10658b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
106602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10661cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
10662b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
106638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
106642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
106668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
106678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
106688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
106698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
106708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
106718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
106728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
106738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
106748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
106762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
106788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
106798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
106802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
106828640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
106838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
106848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
106862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1068716ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
106882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1068916ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
106908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
106912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
106928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1069344757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
106944bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
106954bf89731a90c6e03598950223e19e7be7b95d630glennrp
1069616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1069716ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1069844757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
106992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
107008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
107018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
107028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
107038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
107052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1070616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10707cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1070816ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
107098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
107102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
107118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
107128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1071316ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1071416ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
107152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
107165eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
107175eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
107185eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107191a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
107205eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
107215eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107225eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
107235eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
107245eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
107258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
10726cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
107278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
107288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
107292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
107308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
107318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
107328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
107338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
107348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
107358640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
107398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10740b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
10741b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10746b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
107470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10749e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
107500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10752e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
107530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107575d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
107620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107665d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
107710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10776a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10778823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1078026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1078126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1078226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1078326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1078426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1078526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
107862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1078716ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
10788a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10789a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      /* Don't write any "png:" properties; those are just for "identify" */
10790a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(property,"png:",4) != 0 &&
10791a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10792a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
10793a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
10794823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
10795a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
10796a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10797a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
10798a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
10799a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1080026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
10801c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
10802c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
10803a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy
10804a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#if PNG_LIBPNG_VER >= 14000
10805a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,
10806a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy                 (png_alloc_size_t) sizeof(png_text));
10807a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
10808a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
10809a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
10810c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
10811c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
10812c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
108132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10814c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
10815c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
108162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10817c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
10818c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
108192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10820c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1082126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
10822c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
10823c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
10824c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
10825c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1082626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
108272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10828c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
10829c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
10830c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10831c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
10832c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
10833c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10834c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "    keyword: %s",text[0].key);
10835c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
10836c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
10837c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
10838c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
10839c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1084026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1084126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1084226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
10846cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
108510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
108530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
108575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
108585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
108623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1086803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
108773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
108795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
108825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
108933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
10894edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
108950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10902cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1090416ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1090516ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1090616ea139d53d867211d3bb0fa859a83de653f687ecristy
1090716ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1090816ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1090916ea139d53d867211d3bb0fa859a83de653f687ecristy
10910b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
10911b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
10912b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
10913b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1091416ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
10915b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
109173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
109190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10920edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#ifdef PNG_SETJMP_NOT_THREAD_SAFE
10921edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
10922edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
10923edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
10924edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   /* }  for navigation to beginning of SETJMP-protected block. Revert to
10925edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    *    Throwing an Exception when an error occurs.
10926edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    */
10927edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
10930edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1095116ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1095216ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1096016ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1096116ea139d53d867211d3bb0fa859a83de653f687ecristy%
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
109673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
109685d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109705a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
109715a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
109745a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
109755a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
10976e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
10977130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
10978130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
10979130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
10980e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
10981e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
10982e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
109835a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
109845a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
109853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
109865a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
109875a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
109885a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
109913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
109925a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
109935a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
109945a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
109955a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
109965a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
109993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
110003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
110010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
110025a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
110035a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
110043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
110063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
11008bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
11009bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
11010bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
110113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
110133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
110153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110285a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
110295a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
110305a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
110315a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
110343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
110355a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1103616ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
110403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
110453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
110483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
110503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
11051bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
11052bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
110533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
110553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
11057bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11059bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110613241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
110620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
11063d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
110640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
110650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
110660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
11067cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
110680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
11069d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
11070d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
110715d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
11072d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
11073d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
11074d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
11075d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
110760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
110773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1108016ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1108321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1108421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1108521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
110903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1109521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
110965c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
110975c7cf4e469a4dad7e277783749155932252c52dfglennrp
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11106fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1111173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
111120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
111150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
11121a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
111283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11130b381a2618e8bb9e1e76299676711d0ec1063feabglennrp  value=GetImageOption(image_info,"png:format");
11131b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11132b381a2618e8bb9e1e76299676711d0ec1063feabglennrp  if (value != (char *) NULL)
11133b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
11134b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
11135b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
11136b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
11137b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickFalse;
11138b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickFalse;
11139b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11140b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11141b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11142b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
11143b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickFalse;
11144b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11145b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickFalse;
11146b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11147b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11148b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11149b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        {
11150b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickFalse;
11151b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickFalse;
11152b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11153b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        }
11154b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    }
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
111563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111579c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
111589c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
111599c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111649c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
111659c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
111669c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
111670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111688a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      if (image->alpha_trait == BlendPixelTrait)
1116916ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
111700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111719c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1117216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
111730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1117416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
111783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111799c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
111809c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
111819c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
111820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111838a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      if (image->alpha_trait == BlendPixelTrait)
1118416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
111850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111869c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1118716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
111880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1118916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
111903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
111938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
111979c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
111980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
112009c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
112010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
112039c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
112040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
112069c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
112070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
112099c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
112100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11211bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1121216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11213bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11214bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11215bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11216bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
112189c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11219bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
112230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
112289c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
112290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1123016ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1123116ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1123216ea139d53d867211d3bb0fa859a83de653f687ecristy
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
112349c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
112350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
112379c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
112380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
112409c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
112410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
112439c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
112440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11245bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1124616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11247bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11248bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11249bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11250bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
112513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
112529c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11253d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
112543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
112570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112580dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
112590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
112600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112615d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
112620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
112630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
112640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
112650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
112660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
112680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112695d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
112705d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
112710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
112720dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
112730dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
112740dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11275aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11276aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11277aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
112780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
112800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
112810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
112820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
112840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
112850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
112860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
112880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
112890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
112900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11291104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
112920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
112930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1129426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1129526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11296a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1129726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1129826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1129926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1130026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1130126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1130226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1130326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1130426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11305a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1130626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1130726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1130826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1130926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
113108d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
113118d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
113128d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  value=GetImageArtifact(image,"png:preserve-colormap");
113138d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
113148d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     value=GetImageOption(image_info,"png:preserve-colormap");
113158d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
113168d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
113178d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
113181868258559ddf946fa73ef72dd43507b32623705glennrp  /* Thes compression-level, compression-strategy, and compression-filter
113191868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
113201868258559ddf946fa73ef72dd43507b32623705glennrp   */
113211868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-level");
113221868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
113231868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-level");
113241868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
113251868258559ddf946fa73ef72dd43507b32623705glennrp  {
113261868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
113271868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
113281868258559ddf946fa73ef72dd43507b32623705glennrp       */
113291868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
113301868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
113311868258559ddf946fa73ef72dd43507b32623705glennrp
113320ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
113331868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
113341868258559ddf946fa73ef72dd43507b32623705glennrp
113351868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
113361868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
113371868258559ddf946fa73ef72dd43507b32623705glennrp
113381868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
113391868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
113401868258559ddf946fa73ef72dd43507b32623705glennrp
113411868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
113421868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
113431868258559ddf946fa73ef72dd43507b32623705glennrp
113441868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
113451868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
113461868258559ddf946fa73ef72dd43507b32623705glennrp
113471868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
113481868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
113491868258559ddf946fa73ef72dd43507b32623705glennrp
113501868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
113511868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
113521868258559ddf946fa73ef72dd43507b32623705glennrp
113531868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
113541868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
113551868258559ddf946fa73ef72dd43507b32623705glennrp
113561868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
113571868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
113581868258559ddf946fa73ef72dd43507b32623705glennrp
113591868258559ddf946fa73ef72dd43507b32623705glennrp      else
1136016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
113611868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
113621868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
113631868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
113641868258559ddf946fa73ef72dd43507b32623705glennrp    }
113651868258559ddf946fa73ef72dd43507b32623705glennrp
113661868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-strategy");
113671868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
113681868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-strategy");
113691868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
113701868258559ddf946fa73ef72dd43507b32623705glennrp  {
113711868258559ddf946fa73ef72dd43507b32623705glennrp
113721868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
113731868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
113741868258559ddf946fa73ef72dd43507b32623705glennrp
113751868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
113761868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
113771868258559ddf946fa73ef72dd43507b32623705glennrp
113781868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
113791868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
113801868258559ddf946fa73ef72dd43507b32623705glennrp
113811868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1138298c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
113831868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1138498c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1138598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1138698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
113871868258559ddf946fa73ef72dd43507b32623705glennrp
113881868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1138998c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
113901868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1139198c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1139298c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1139398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
113941868258559ddf946fa73ef72dd43507b32623705glennrp
113951868258559ddf946fa73ef72dd43507b32623705glennrp      else
1139616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
113971868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
113981868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
113991868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
114001868258559ddf946fa73ef72dd43507b32623705glennrp    }
114011868258559ddf946fa73ef72dd43507b32623705glennrp
114021868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-filter");
114031868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
114041868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-filter");
114051868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
114061868258559ddf946fa73ef72dd43507b32623705glennrp  {
114071868258559ddf946fa73ef72dd43507b32623705glennrp
114081868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
114091868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
114101868258559ddf946fa73ef72dd43507b32623705glennrp       *
114111868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
114121868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
114131868258559ddf946fa73ef72dd43507b32623705glennrp       */
114141868258559ddf946fa73ef72dd43507b32623705glennrp
114151868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
114161868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
114171868258559ddf946fa73ef72dd43507b32623705glennrp
114181868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"1") == 0)
114191868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
114201868258559ddf946fa73ef72dd43507b32623705glennrp
114211868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
114221868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
114231868258559ddf946fa73ef72dd43507b32623705glennrp
114241868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
114251868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
114261868258559ddf946fa73ef72dd43507b32623705glennrp
114271868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
114281868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
114291868258559ddf946fa73ef72dd43507b32623705glennrp
114301868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
114311868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
114321868258559ddf946fa73ef72dd43507b32623705glennrp
114331868258559ddf946fa73ef72dd43507b32623705glennrp      else
1143416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
114351868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
114361868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
114371868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
114381868258559ddf946fa73ef72dd43507b32623705glennrp    }
114391868258559ddf946fa73ef72dd43507b32623705glennrp
1144003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1144103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
114425c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
114435c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
114445c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11445acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
114465c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
11447acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11448acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11449acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
11450acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
114515c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11452acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
114535c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
1145426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11455acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11456acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
11457acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11458acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1145903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1146003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1146126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1146203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1146303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1146426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1146503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1146626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1146703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
114682cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
114692cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
114702cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
114712cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
114722cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
114732cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
114742cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
114752cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1147603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1147703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1147803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1147903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1148003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1148103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1148203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1148303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1148403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1148503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
11486a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
1148703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1148803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1148903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1149003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1149103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1149203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1149303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1149403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
11495a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1149603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1149703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1149803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1149903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1150003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
115012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1150203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1150303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1150403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1150503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
11506a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
1150703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1150803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1150903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1151003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1151103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1151203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1151303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1151403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
11515a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1151603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1151703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1151803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1151903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
115202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1152103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1152203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
115232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1152403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1152503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
115262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11527a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11528a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
11529a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1153003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1153103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
115322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1153403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
115352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1153703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
115382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1153903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1154003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1154103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1154203812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
115432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1154403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1154503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
115462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1154703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1154803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
115492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1155003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1155103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
115522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11553a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11554a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
115552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1155603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1155703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
115582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11559a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11560a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
11561a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1156203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1156303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
115642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1156503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1156603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
115672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1156803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1156903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
115702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1157103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11572ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1157326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1157426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
115755c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
115765c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
115775c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11578acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
115795c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
11580acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11581acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11582acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
11583acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
115845c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11585acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
115865c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
1158726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11588acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11589acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
11590acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11591acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1159203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1159303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1159403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1159503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1159626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1159703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1159826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1159903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
116002cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
116012cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
116022cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116032cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
116042cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
116052cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116062cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
116072cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1160803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1160903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1161003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1161103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1161203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1161303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1161403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1161503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1161603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
11617a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickFalse;
1161803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1161903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1162003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1162103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1162203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1162303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1162403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1162503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
11626a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1162703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1162803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1162903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1163003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1163103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
116322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1163303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1163403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1163503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1163603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
11637a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickTrue;
1163803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1163903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1164003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1164103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1164203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1164303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1164403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1164503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
11646a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1164703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1164803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1164903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1165003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
116512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1165203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1165303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
116542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1165503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1165603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
116572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11658a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11659a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
11660a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1166103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1166203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
116632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1166403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1166503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
116662cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1166703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1166803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
116692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1167003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1167103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1167203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1167303812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
116742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1167503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1167603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
116772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1167803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1167903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
116802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1168103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1168203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
116832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11684a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11685a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
116862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1168703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1168803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
116892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11690a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11691a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
11692a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1169303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1169403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
116952cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1169603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1169703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
116982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1169903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1170003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
117012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1170203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11703ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1170426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1170526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1170603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1170726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1170826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
117095d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1171026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1171126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1171226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1171326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1171426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1171526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
11716a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
11717a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11718a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1171926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1172026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1172126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1172226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1172326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1172426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1172526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1172626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1172726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1172826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1172926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1173026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1173126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1173226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1173326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1173426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1173526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1173626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1173726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1173826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1173926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1174026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1174126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1174226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1174326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1174426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
11745a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
11746a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11747a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1174826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1174926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1175026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1175126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1175226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1175326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1175426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1175526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1175626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1175726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1175826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11759b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
117603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1176116ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
117623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
117640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
117663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
117670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
117693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
117703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
117723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
117743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1177516ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
117763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
117773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
117783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
117793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
117813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
117823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1178403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
117853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
117863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
117883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
117893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
117913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
117923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
117933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
117943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
117963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
117973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
117983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
117993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
118003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11801bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1180259575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
118033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
118043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
11806fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
118073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
118093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
118103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
118113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
118133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
118148a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     image_info->type==TrueColorMatteType || image->alpha_trait == BlendPixelTrait;
118153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1181659575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1181759575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1181859575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1181959575fa5c228308a41d7f5028390be2083aaaf6dglennrp
11820750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1182159575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1182259575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1182359575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1182459575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
118253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
118273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
118290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
118313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
118323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1183316ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
118340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
118360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
118383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
118390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
118413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
118430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1184416ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
118453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
118463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
118473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
118488a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      jpeg_image->alpha_trait=UndefinedPixelTrait;
118498f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1185016ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1185116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
118523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
118533b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy      (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
118543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
118553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1185659575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1185759575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1185859575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1185959575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1186059575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1186159575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
118623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
118643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
118663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
118677fb2652ba366fc984d1dbb0c66560b91c57dab78cristy    TrueColorType && IsImageGray(image,exception))
118683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
118693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1187059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1187159575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1187259575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1187359575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1187459575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1187559575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
1187659575fa5c228308a41d7f5028390be2083aaaf6dglennrp        if (transparent)
1187759575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1187859575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1187959575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1188059575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1188159575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1188259575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1188359575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1188459575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1188559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1188659575fa5c228308a41d7f5028390be2083aaaf6dglennrp
118873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
118883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
118903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
118913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
118923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
118933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1189416ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
118953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1189616ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
118973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
118983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
118993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
119003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
119013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
119033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
119043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
119053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11906cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
11907cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
11908cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
119093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1191016ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
119113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1191316ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
119143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
119153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
119163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
119183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1191916ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
119203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1192216ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
119233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
119253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
119263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
119273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
119283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
119303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1193116ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
119323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
119330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
119353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11936e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
11937e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
119383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
119413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
119423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
119433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
119443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
119473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
119483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1194903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
119504e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
119514e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
119523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
119533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
119543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
119553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
119563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
119573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
119583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
119593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
119603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
119613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
119623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
119633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
119643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11965f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
119660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11968f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
119690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
119720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
119750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
119780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
119810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
119840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
119870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
119900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
119933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
11996cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
119973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
119993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
120003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
120013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
120033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
120043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
120053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
120063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
120073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
120093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
120103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
120113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
120123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12013bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
120143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
120153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
120173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
120183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
120193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
12020bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
120213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1202203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
120233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
120243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
120253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
120263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
120273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
120283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
120293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
120303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
120313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
120323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
120333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
120343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
120353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
120373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
120393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
120403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
120413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
120423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1204303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
120440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
12046e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12047cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12048e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
120490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12051e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12052cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12053e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
120540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
120563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
120573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
120593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
120613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
120623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
120633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
120643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
120653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
120663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1206703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1206835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
120693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
120703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
120713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
120720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
120743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
120753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
120763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
120773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
120783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
120803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
120813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
120823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
120833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1208403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
120853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1208635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1208735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
120883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1208935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1209035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
120913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1209235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1209335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
120943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1209535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1209635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
120973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
120983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
120993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
121003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
121010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1210216ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
121033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
121053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
121063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
121073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
121083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1210903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
121103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
121113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1211235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1211316ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
121140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1211535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1211616ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
121170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
121193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
121200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
121223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
121233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
121243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1212535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1212616ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
121270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1212835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1212916ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
121300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
121323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
121330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
121353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1213616ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1213716ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
121383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
121393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
121403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
121413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
121423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
121433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
121443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
121463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
121483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
121493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
121513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1215203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12153bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12154bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
121563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
121573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
121583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
121593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
121603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
121623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1216303812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
121643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
121653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
121663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
121673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
121683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
121693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
121703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
121733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
121753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12176bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
121773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
121783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12179bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
121803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
121813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
121833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
121843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12185e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12186f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
121873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
121893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
121903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12191bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
121923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
121933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
121943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
121950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
121973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
121983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12199bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1220003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
122013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
122023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
122033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
122043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
122050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
122073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
122083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
122093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12210e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12211e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
122123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
122133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
122143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
122173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
122193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12221e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12222bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
122233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1222403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
122253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
122263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
122273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
122283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
122293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
122303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
122323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
122333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
122353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
122383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
122393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
122403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
122453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1224616ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
122473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
122483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
122523b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
122533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
122543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1225616ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
122573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12260e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12261e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
122623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
122643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
122650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1226659575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1226759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
122683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
122693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
122740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1227516ea139d53d867211d3bb0fa859a83de653f687ecristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,exception);
122760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12280e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12281e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
122823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12284e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
122853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
122860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12288bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
122893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1229003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
122913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
122923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
122933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
122943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
122963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
122973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
122983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
122993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12301cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
123043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
123053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1230603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
123130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
123153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
123163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
123193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
123323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
123343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1233516ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1233616ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
123373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
123393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
123413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
123423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
123433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1234416ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1234516ea139d53d867211d3bb0fa859a83de653f687ecristy%
123463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1234816ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1234916ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
123503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
123513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1235221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1235303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
123553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
123573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
123583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
123633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
123653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12367fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1236816ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
123693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
123743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1237673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
123833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
123853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
123873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1238816ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
123893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
123923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
123933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
123963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
123973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
123983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1239916ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1240016ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
124013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
124043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
124063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1240921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
124103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
124113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1241203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1241303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1241403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
124153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
124163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
124173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
124193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
124203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
124213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
124263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
124293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
124303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
124313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12432bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
124333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
124343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
124363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
124373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
124403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12442bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12445bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
124463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
124473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
124483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12449d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
124503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
124513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
124523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
124533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
124543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
124573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
124583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
124593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
124603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
124613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
124623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12463fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1246416ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
124653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
124703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
124713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1247273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
124733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
124743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
124753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
124773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
124783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
124793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
124803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
124813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
124823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
124853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
124863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
124873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
124883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
124893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
124903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
124923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
124933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
124953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
124963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
124973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
124993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
125003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
125013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
125033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
125043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
125083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
125093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
125103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
125130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12515e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
125160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
125213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
125223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12524e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
125250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12527e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
125280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125298a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        if (p->alpha_trait)
125303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
125320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
125360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
125383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
125400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
125440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
125463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12547e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
125480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
125503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
125520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
125543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
125563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
125603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
125623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
125633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
125643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
125653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
125663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
125673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
125693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
125723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
125733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
125753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
125763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
125773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
125793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
125843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
125873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
125893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
125903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
125943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
125953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
125963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
125993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
126003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
126043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
126053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
126063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
126073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
126083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
126093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
126103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
126113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
126123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
126133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
126143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
126150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
126183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
126190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
126220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126238a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        if (next_image->alpha_trait)
126243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
126250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
126278a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (next_image->alpha_trait || next_image->page.x || next_image->page.y ||
126283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
126293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
126303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
126310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
126333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
126340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
126360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
126383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
126393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
126400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
126423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
126433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
126443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
126453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
126468a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        if (image->alpha_trait == BlendPixelTrait)
126473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
126480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
126503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
126517fb2652ba366fc984d1dbb0c66560b91c57dab78cristy            if (IsImageGray(image,exception) == MagickFalse)
126523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
126533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
126543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
126553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
126573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
126583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
126593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
126613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
126643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
126680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
126703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
126710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
126750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1267716ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1267816ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
126793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
126800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
126833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
126883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
126893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
126903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
126933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
126963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
126973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
126983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
126993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
127003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
127013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
127023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
127053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
127063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
127073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
127103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
127113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
127133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
127143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
127153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
127173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
127180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
127203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
127223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
127283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
127293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
127303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
127320261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
12733d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
12734d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1273516ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1273616ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
12737d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
12738d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
12739d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
127423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
127433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
12745cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
12746cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
127490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
127520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
127543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
127550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
127573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
127583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
127603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
127613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
127693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
127753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1277603812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
127774e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
127784e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
127793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
127803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
127823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
127833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
127863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
127890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
127973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
127980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
128013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
128073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
128083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
128100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
128123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
128133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
128163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
128190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
128213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
128253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
128263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
128333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
12837bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1283803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
128413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
128423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
128453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
128483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1285203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
128563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
128570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
128600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
128630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12867e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
12868e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
128690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12872e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
128730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
128753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12876e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
128793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
128803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
128813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
128823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
128833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
128843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
128853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
128863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
128873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
128883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
128893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
128903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
128913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1289203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
128930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
12895e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
12896cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
12897e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
128980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
12900e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
12901cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
12902cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
129030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
129053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
129063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
129073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
129080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
129113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
129123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
129133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
129163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1291803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1291935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
129203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
129243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
129263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
129273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
129283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
129303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
129313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
129323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1293403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1293635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1293735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1293935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1294035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1294235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1294335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
129443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1294535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1294635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
129503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1295216ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
129553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
129563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
129573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
129583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1295903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
129600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
129623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1296335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1296416ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
129650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1296635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1296716ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
129680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
129710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
129743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1297635ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1297716ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
129780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1297935ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1298016ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
129810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
129833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
129840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
129863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1298716ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1298816ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
129893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
129903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
129913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
129923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
129963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
129973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
129983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
129998a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     if (write_mng && (image->alpha_trait || image->page.x > 0 ||
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
130013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
130043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
130063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1300703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
130083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
130093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
130103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
130113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
130123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
130133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
130153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
130163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
130173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
130183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
130193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1302003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
130213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
130243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
130253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
130283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
130293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
130303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
13031bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
130323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
130333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
130353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
130363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
130373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
130383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
130393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1304003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
130410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13042bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
130433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1304416ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1304516ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1304616ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1304716ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1304816ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1304916ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
130503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
130510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
130533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
130563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
130583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
130603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
130633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
130653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
130663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
130673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
130723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
130733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
130743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
130753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
130763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
130773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
130793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
130803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
130813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
130823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
130833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
130843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
130853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
130863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
130873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
130883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
13089bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
130903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
130913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
130933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
130943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1309503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
130960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13097bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
130983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
130993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
131003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
131013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
131023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
131030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
131073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
131083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
131103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
131113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
131123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
131133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
131143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
131153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
131173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
131183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
131193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
131213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
131223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
131233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
131243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
131273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
131293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
131303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
131313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
131333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
131343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
131353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1313603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
131373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
131383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
131393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
131403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
131413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
131423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
131433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
131463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
131473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
131503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
131533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
131553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
131563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
131573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
131583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
131593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
131603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
131613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
131623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
131633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
131643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1316503812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
131663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
131673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
131683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
131693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
131703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
131713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
131723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
131733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
131743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
131753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
131763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1317703812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
131783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
131793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
131803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
131813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
131823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
131833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
131843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
131853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
131863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
131873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
131883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
131894e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
131903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
131913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
131923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
131933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
131953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
131963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
131973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
131983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
131993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
132013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
132023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
132033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
132043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
132053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1320616ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
132073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
132083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
132093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
132103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
132113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
132123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
132133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
132143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
132152f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13216b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
132178d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
132182f2e514554975d510c88df54de98c6cdc1080f1cglennrp
132192f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
132202f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
132212f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13222a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
132232f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
132242f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
132252f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
132262f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
132272f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
132282f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
132292f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
132302f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13231a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
132322f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
132332f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
132342f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
132352f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1323616ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
132373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
132383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
132403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
132413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
132423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
132433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
132443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
132453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
132463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
132473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
132483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
132493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
132503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
132510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
132533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
132540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
132560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
132583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
132593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
132603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
132613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
132623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
132633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
132643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
132653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1326603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
132673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
132683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
132693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
132703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
132713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
132723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
132733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
132743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
132750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
132773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
132780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
132803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13281d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1328239992b4dd9b12ef752d55b8e402c069698851f72glennrp
132833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
132843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
132853bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
132863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
132873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
132880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
132903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
132913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1329239992b4dd9b12ef752d55b8e402c069698851f72glennrp
132933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
132943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
132953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
132963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13297d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
132983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13299