png.c revision 6dfc26699a1aacdec9771115c4dcaf6c5c0a8f98
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                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                           Glenn Randers-Pehrson                             %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                               November 1997                                 %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21b56bb24a985ca4366713bcd8ffdfacbb48a98a2fcristy%  Copyright 1999-2015 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
132ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp/* Table of recognized sRGB ICC profiles */
133ecab7d7b7fc598881ff3c72240381caa5c444a56glennrpstruct sRGB_info_struct
134ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp{
135ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    png_uint_32 len;
136ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    png_uint_32 crc;
137ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    png_byte intent;
138ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp};
139ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
140ecab7d7b7fc598881ff3c72240381caa5c444a56glennrpconst struct sRGB_info_struct sRGB_info[] =
141ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp{
142c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* ICC v2 perceptual sRGB_IEC61966-2-1_black_scaled.icc */
143ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    { 3048, 0x3b8772b9UL, 0},
144ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
145c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* ICC v2 relative sRGB_IEC61966-2-1_no_black_scaling.icc */
146ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    { 3052, 0x427ebb21UL, 1},
147ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
148c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* ICC v4 perceptual sRGB_v4_ICC_preference_displayclass.icc */
149ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {60988, 0x306fd8aeUL, 0},
150ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
151c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* ICC v4 perceptual sRGB_v4_ICC_preference.icc perceptual */
152ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     {60960, 0xbbef7812UL, 0},
153ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
154c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* HP? sRGB v2 media-relative sRGB_IEC61966-2-1_noBPC.icc */
155ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     { 3024, 0x5d5129ceUL, 1},
156ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
157ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     /* HP-Microsoft sRGB v2 perceptual */
158ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     { 3144, 0x182ea552UL, 0},
159ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
160ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     /* HP-Microsoft sRGB v2 media-relative */
161ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     { 3144, 0xf29e526dUL, 1},
162ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
163c241d3cdc951647513766801b3f1cfc74b773b5eglennrp     /* Facebook's "2012/01/25 03:41:57", 524, "TINYsRGB.icc" */
164c241d3cdc951647513766801b3f1cfc74b773b5eglennrp     {  524, 0xd4938c39UL, 0},
165c241d3cdc951647513766801b3f1cfc74b773b5eglennrp
166c241d3cdc951647513766801b3f1cfc74b773b5eglennrp     /* "2012/11/28 22:35:21", 3212, "Argyll_sRGB.icm") */
167c241d3cdc951647513766801b3f1cfc74b773b5eglennrp     { 3212, 0x034af5a1UL, 0},
168c241d3cdc951647513766801b3f1cfc74b773b5eglennrp
169ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     /* Not recognized */
170ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     {    0, 0x00000000UL, 0},
171ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp};
172ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
1738e58efdecda887b08ef730d68290a61081ef2566glennrp/* Macros for left-bit-replication to ensure that pixels
17416ea139d53d867211d3bb0fa859a83de653f687ecristy * and PixelInfos all have the same image->depth, and for use
1758e58efdecda887b08ef730d68290a61081ef2566glennrp * in PNG8 quantization.
1768e58efdecda887b08ef730d68290a61081ef2566glennrp */
1778e58efdecda887b08ef730d68290a61081ef2566glennrp
1788e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR01: Replicate top bit */
1798e58efdecda887b08ef730d68290a61081ef2566glennrp
18005001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR01PacketRed(pixelpacket) \
1818e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=(ScaleQuantumToChar((pixelpacket).red) < 0x10 ? \
1828e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1838e58efdecda887b08ef730d68290a61081ef2566glennrp
18491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketGreen(pixelpacket) \
1858e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=(ScaleQuantumToChar((pixelpacket).green) < 0x10 ? \
1868e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1878e58efdecda887b08ef730d68290a61081ef2566glennrp
18891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketBlue(pixelpacket) \
1898e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=(ScaleQuantumToChar((pixelpacket).blue) < 0x10 ? \
1908e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1918e58efdecda887b08ef730d68290a61081ef2566glennrp
19216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PacketAlpha(pixelpacket) \
19316ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=(ScaleQuantumToChar((pixelpacket).alpha) < 0x10 ? \
1948e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1958e58efdecda887b08ef730d68290a61081ef2566glennrp
19691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGB(pixelpacket) \
197bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
19805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR01PacketRed((pixelpacket)); \
19991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketGreen((pixelpacket)); \
20091d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketBlue((pixelpacket)); \
201bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2028e58efdecda887b08ef730d68290a61081ef2566glennrp
20391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGBO(pixelpacket) \
204bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
20591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketRGB((pixelpacket)); \
20616ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PacketAlpha((pixelpacket)); \
207bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2088e58efdecda887b08ef730d68290a61081ef2566glennrp
209ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR01PixelRed(pixel) \
210360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelRed(image, \
211360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelRed(image,(pixel))) < 0x10 ? \
212c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
2138e58efdecda887b08ef730d68290a61081ef2566glennrp
21454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelGreen(pixel) \
215360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelGreen(image, \
216360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelGreen(image,(pixel))) < 0x10 ? \
217c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
2188e58efdecda887b08ef730d68290a61081ef2566glennrp
21954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelBlue(pixel) \
220360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelBlue(image, \
221360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelBlue(image,(pixel))) < 0x10 ? \
222c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
2238e58efdecda887b08ef730d68290a61081ef2566glennrp
22416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelAlpha(pixel) \
225360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelAlpha(image, \
226360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) < 0x10 ? \
227c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
2288e58efdecda887b08ef730d68290a61081ef2566glennrp
22954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelRGB(pixel) \
230bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
231ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR01PixelRed((pixel)); \
23254cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelGreen((pixel)); \
23354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelBlue((pixel)); \
234bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2358e58efdecda887b08ef730d68290a61081ef2566glennrp
23616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelRGBA(pixel) \
237bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
23854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelRGB((pixel)); \
23916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PixelAlpha((pixel)); \
240bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2418e58efdecda887b08ef730d68290a61081ef2566glennrp
2428e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR02: Replicate top 2 bits */
2438e58efdecda887b08ef730d68290a61081ef2566glennrp
24405001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR02PacketRed(pixelpacket) \
2458e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2468e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xc0; \
2478e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2488e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2498e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketGreen(pixelpacket) \
2518e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2528e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xc0; \
2538e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2548e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2558e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketBlue(pixelpacket) \
2578e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2588e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xc0; \
2598e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
2608e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2618e58efdecda887b08ef730d68290a61081ef2566glennrp   }
26216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PacketAlpha(pixelpacket) \
2638e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
26416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xc0; \
26516ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum( \
2668e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2678e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2688e58efdecda887b08ef730d68290a61081ef2566glennrp
26991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGB(pixelpacket) \
270bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
27105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR02PacketRed((pixelpacket)); \
27291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketGreen((pixelpacket)); \
27391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue((pixelpacket)); \
274bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2758e58efdecda887b08ef730d68290a61081ef2566glennrp
27691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGBO(pixelpacket) \
277bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
27891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketRGB((pixelpacket)); \
27916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PacketAlpha((pixelpacket)); \
280bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2818e58efdecda887b08ef730d68290a61081ef2566glennrp
282ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR02PixelRed(pixel) \
2838e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
28416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
2858e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
28616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
28716ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
28816ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2898e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelGreen(pixel) \
2918e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
29216ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
2938e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
29416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
29516ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
29616ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2978e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29854cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelBlue(pixel) \
2998e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3008e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
30116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xc0; \
30216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
30316ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
30416ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
3058e58efdecda887b08ef730d68290a61081ef2566glennrp   }
30616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelAlpha(pixel) \
3078e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3088e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
30916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xc0; \
31016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image, ScaleCharToQuantum( \
31116ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
31216ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel) ); \
3138e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3148e58efdecda887b08ef730d68290a61081ef2566glennrp
31554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelRGB(pixel) \
316bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
317ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR02PixelRed((pixel)); \
31854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelGreen((pixel)); \
31954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelBlue((pixel)); \
320bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3218e58efdecda887b08ef730d68290a61081ef2566glennrp
32216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelRGBA(pixel) \
323bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
32454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelRGB((pixel)); \
32516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PixelAlpha((pixel)); \
326bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3278e58efdecda887b08ef730d68290a61081ef2566glennrp
3288e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR03: Replicate top 3 bits (only used with opaque pixels during
3298e58efdecda887b08ef730d68290a61081ef2566glennrp   PNG8 quantization) */
3308e58efdecda887b08ef730d68290a61081ef2566glennrp
33105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR03PacketRed(pixelpacket) \
3328e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3338e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xe0; \
3348e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
3358e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3368e58efdecda887b08ef730d68290a61081ef2566glennrp   }
33791d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketGreen(pixelpacket) \
3388e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3398e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xe0; \
3408e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
3418e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
34391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketBlue(pixelpacket) \
3448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3458e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xe0; \
3468e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
3478e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3488e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3498e58efdecda887b08ef730d68290a61081ef2566glennrp
35091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketRGB(pixelpacket) \
351bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
35205001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR03PacketRed((pixelpacket)); \
35391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketGreen((pixelpacket)); \
35491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketBlue((pixelpacket)); \
355bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3568e58efdecda887b08ef730d68290a61081ef2566glennrp
357ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR03PixelRed(pixel) \
3588e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
35916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3608e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
36116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
36216ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
36416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Green(pixel) \
3658e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
36616ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3678e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
36816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
36916ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3708e58efdecda887b08ef730d68290a61081ef2566glennrp   }
37116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Blue(pixel) \
3728e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
37316ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelBlue(image,(pixel))) \
3748e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
37516ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
37616ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3778e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3788e58efdecda887b08ef730d68290a61081ef2566glennrp
37916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03RGB(pixel) \
380bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
381ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR03PixelRed((pixel)); \
38216ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Green((pixel)); \
38316ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Blue((pixel)); \
384bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3858e58efdecda887b08ef730d68290a61081ef2566glennrp
3868e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR04: Replicate top 4 bits */
3878e58efdecda887b08ef730d68290a61081ef2566glennrp
38805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR04PacketRed(pixelpacket) \
3898e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3908e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xf0; \
3918e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3928e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketGreen(pixelpacket) \
3948e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3958e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xf0; \
3968e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3978e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketBlue(pixelpacket) \
3998e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4008e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xf0; \
4018e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
4028e58efdecda887b08ef730d68290a61081ef2566glennrp   }
40316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PacketAlpha(pixelpacket) \
4048e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
40516ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xf0; \
40616ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
4078e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4088e58efdecda887b08ef730d68290a61081ef2566glennrp
40991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGB(pixelpacket) \
410bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
41105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR04PacketRed((pixelpacket)); \
41291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketGreen((pixelpacket)); \
41391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketBlue((pixelpacket)); \
414bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4158e58efdecda887b08ef730d68290a61081ef2566glennrp
41691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGBO(pixelpacket) \
417bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
41891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB((pixelpacket)); \
41916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PacketAlpha((pixelpacket)); \
420bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4218e58efdecda887b08ef730d68290a61081ef2566glennrp
422ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR04PixelRed(pixel) \
4238e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
42416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
4258e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
42616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
42716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4288e58efdecda887b08ef730d68290a61081ef2566glennrp   }
42954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelGreen(pixel) \
4308e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
43116ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
4328e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
43316ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
43416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4358e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelBlue(pixel) \
4378e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4388e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
43916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xf0; \
44016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
44116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
44316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelAlpha(pixel) \
4448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4458e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
44616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xf0; \
44716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
44816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4498e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4508e58efdecda887b08ef730d68290a61081ef2566glennrp
45154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelRGB(pixel) \
452bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
453ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR04PixelRed((pixel)); \
45454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelGreen((pixel)); \
45554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelBlue((pixel)); \
456bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4578e58efdecda887b08ef730d68290a61081ef2566glennrp
45816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelRGBA(pixel) \
459bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
46054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelRGB((pixel)); \
46116ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PixelAlpha((pixel)); \
462bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4638e58efdecda887b08ef730d68290a61081ef2566glennrp
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
469868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef PNG_SETJMP_SUPPORTED
470868fff35aea4233c40dca33989293cb5bc91601aglennrp# ifndef IMPNG_SETJMP_IS_THREAD_SAFE
471868fff35aea4233c40dca33989293cb5bc91601aglennrp#   define IMPNG_SETJMP_NOT_THREAD_SAFE
472868fff35aea4233c40dca33989293cb5bc91601aglennrp# endif
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
474868fff35aea4233c40dca33989293cb5bc91601aglennrp# ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
476cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  *ping_semaphore = (SemaphoreInfo *) NULL;
477868fff35aea4233c40dca33989293cb5bc91601aglennrp# endif
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
52985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
53085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
53185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
53285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
53385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
53485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
53585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
53685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
53785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
53885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
53985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
54085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
54185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
54285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
54385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
54485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
54585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
54685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
54785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
54885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
54985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
55085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
55185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
55285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
55385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
55485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
55585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
55685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
55785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
55885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
55985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
56085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
56185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
56485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
56585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
56685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
56785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
56885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
56985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
572689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
573689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp/* Other known chunks that are not yet supported by ImageMagick: */
57485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
57585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
57685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
57785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
57885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
57985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
58085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
581689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
603bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
681bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72735ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
737b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
738b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
739b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
7571868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_level,
7581868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_strategy,
7591868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_filter,
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
762fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png32,
763fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png48,
764fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png64;
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
80026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
80126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
80226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
803a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
80426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
80526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
80626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
80726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
80826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
80926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
81026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
81126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
812a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
81326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
81426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
8158d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_exclude_zTXt,
816ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_colormap,
817ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  /* Added at version 6.8.5-7 */
818fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_preserve_iCCP,
819fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  /* Added at version 6.8.9-9 */
820fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_exclude_tIME;
82126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
82916ea139d53d867211d3bb0fa859a83de653f687ecristy  WritePNGImage(const ImageInfo *,Image *,ExceptionInfo *);
8300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
83216ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteMNGImage(const ImageInfo *,Image *,ExceptionInfo *);
8330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
83616ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteJNGImage(const ImageInfo *,Image *,ExceptionInfo *);
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
8400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
841fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
8430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
84416ea139d53d867211d3bb0fa859a83de653f687ecristyLosslessReduceDepthOK(Image *image,ExceptionInfo *exception)
8450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
8469d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp    /* Reduce bit depth if it can be reduced losslessly from 16+ to 8.
84767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
84867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * This is true if the high byte and the next highest byte of
84967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * each sample of the image, the colormap, and the background color
8503faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are equal to each other.  We check this by seeing if the samples
8513faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are unchanged when we scale them down to 8 and back up to Quantum.
85267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
85367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * We don't use the method GetImageDepth() because it doesn't check
8543faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * background and doesn't handle PseudoClass specially.
8559d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp     */
85605a549971fd661147ade177e2bc10f6cfcfc32b4glennrp
8573faa9a3fb01696daaf976d595f492cb530bffb21glennrp#define QuantumToCharToQuantumEqQuantum(quantum) \
8583faa9a3fb01696daaf976d595f492cb530bffb21glennrp  ((ScaleCharToQuantum((unsigned char) ScaleQuantumToChar(quantum))) == quantum)
8593faa9a3fb01696daaf976d595f492cb530bffb21glennrp
86067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    MagickBooleanType
86167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      ok_to_reduce=MagickFalse;
86267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
86303e11f6e8d7f01a32b53d7e8e6a3bfd5ef1c5c9dglennrp    if (image->depth >= 16)
8640c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
8650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
86616ea139d53d867211d3bb0fa859a83de653f687ecristy        const Quantum
8670c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
8680c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8690c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
8703faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.red) &&
8713faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.green) &&
8723faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.blue) ?
8733faa9a3fb01696daaf976d595f492cb530bffb21glennrp           MagickTrue : MagickFalse;
8740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
8760c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
8770c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
8780c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8790c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
8800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
8813faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=(
8823faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
8833faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].red) &&
8843faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
8853faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].green) &&
8863faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
8873faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].blue)) ?
8883faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
8893faa9a3fb01696daaf976d595f492cb530bffb21glennrp
8900c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
8913faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   break;
8920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
8930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
8940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
8960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
8970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
8980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
8990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
9000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
9020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
9030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
9050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
90616ea139d53d867211d3bb0fa859a83de653f687ecristy              p=GetVirtualPixels(image,0,y,image->columns,1,exception);
9070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
90816ea139d53d867211d3bb0fa859a83de653f687ecristy              if (p == (const Quantum *) NULL)
9090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
9100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
9110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
9120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
9130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
9150c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
9163faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=
91716ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelRed(image,p)) &&
91816ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelGreen(image,p)) &&
91916ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelBlue(image,p)) ?
9203faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
9210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
9230c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
9240c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
92516ea139d53d867211d3bb0fa859a83de653f687ecristy                p+=GetPixelChannels(image);
9260c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
9278640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
9280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
9290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
9300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
9310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9320c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
9330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
9340c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
935fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    OK to reduce PNG bit depth to 8 without loss of info");
9360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
937a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
938a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
939a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
940fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    Not OK to reduce PNG bit depth to 8 without loss of info");
941a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
9420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
9430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9440c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
9450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
9460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
9470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9481a56e9c9268976936eeab9fe97eb664b847e444cglennrpstatic const char* PngColorTypeToString(const unsigned int color_type)
9491a56e9c9268976936eeab9fe97eb664b847e444cglennrp{
9501a56e9c9268976936eeab9fe97eb664b847e444cglennrp  const char
9511a56e9c9268976936eeab9fe97eb664b847e444cglennrp    *result = "Unknown";
9521a56e9c9268976936eeab9fe97eb664b847e444cglennrp
9531a56e9c9268976936eeab9fe97eb664b847e444cglennrp  switch (color_type)
9541a56e9c9268976936eeab9fe97eb664b847e444cglennrp    {
9551a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY:
9561a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray";
9571a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9581a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY_ALPHA:
9591a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray+Alpha";
9601a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9611a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_PALETTE:
9621a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Palette";
9631a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9641a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB:
9651a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB";
9661a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9671a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB_ALPHA:
9681a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB+Alpha";
9691a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9701a56e9c9268976936eeab9fe97eb664b847e444cglennrp    }
9711a56e9c9268976936eeab9fe97eb664b847e444cglennrp
9721a56e9c9268976936eeab9fe97eb664b847e444cglennrp  return result;
9731a56e9c9268976936eeab9fe97eb664b847e444cglennrp}
9741a56e9c9268976936eeab9fe97eb664b847e444cglennrp
975e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
976cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
9770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
978e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
979e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
980e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
981e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
9820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
983e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
984e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
9850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
986e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
987e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
9880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
989e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
990e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
9910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
992e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
993e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
994e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
995e610a071534e448c46460a5aa39ede33bf56b329glennrp}
996e610a071534e448c46460a5aa39ede33bf56b329glennrp
997e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
998cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_from_PNG_RenderingIntent(const int ping_intent)
9990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1000cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  switch (ping_intent)
1001e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1002e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
1003e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
10040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1005e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
1006e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
10070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1008e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
1009e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
10100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1011e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
1012e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
10130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1014e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1015e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
1016e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
1017e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1018e610a071534e448c46460a5aa39ede33bf56b329glennrp
10199d8c12213abd15fee2d84da62d3e5145d9db06cdcristystatic const char *
102098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrpMagick_RenderingIntentString_from_PNG_RenderingIntent(const int ping_intent)
102198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp{
102298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  switch (ping_intent)
102398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
102498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 0:
102598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Perceptual Intent";
102698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
102798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 1:
102898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Relative Intent";
102998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
103098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 2:
103198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Saturation Intent";
103298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
103398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 3:
103498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Absolute Intent";
103598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
103698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    default:
103798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Undefined Intent";
103898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
103998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp}
104098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
1041d9ecd04e9c567113b4b605cf76681cbb37c093cdcristystatic const char *
10425dff435eceea4f80207a906b11e65aed48fe3f27glennrpMagick_ColorType_from_PNG_ColorType(const int ping_colortype)
10435dff435eceea4f80207a906b11e65aed48fe3f27glennrp{
10445dff435eceea4f80207a906b11e65aed48fe3f27glennrp  switch (ping_colortype)
10455dff435eceea4f80207a906b11e65aed48fe3f27glennrp  {
10465dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 0:
10475dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Grayscale";
10485dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10495dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 2:
10505dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Truecolor";
10515dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10525dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 3:
10535dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Indexed";
10545dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10555dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 4:
10565dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "GrayAlpha";
10575dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10585dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 6:
10595dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "RGBA";
10605dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10615dff435eceea4f80207a906b11e65aed48fe3f27glennrp    default:
10625dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "UndefinedColorType";
10635dff435eceea4f80207a906b11e65aed48fe3f27glennrp    }
10645dff435eceea4f80207a906b11e65aed48fe3f27glennrp}
10655dff435eceea4f80207a906b11e65aed48fe3f27glennrp
1066d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
10990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
11020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
11360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
11390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
11720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
11750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1184d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1185bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1207a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1215a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122803812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
122903812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1233e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
1234e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1236d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1242d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
1324f54e295d6fa414fa04aa4f43767c20eda8ae555eglennrp%    the original PNG from files that have been converted to Xcode-PNG,
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
13448fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (length != 0)
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13553b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy          (void) FormatLocaleString(msg,MaxTextExtent,
1356e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1357e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1385bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13988fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (length != 0)
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
14010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
14040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
14220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
14568fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (length != 0)
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1461bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
14620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1476bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
14810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
14840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
14870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1488bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
15100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
15150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1528bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1530bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
153421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
153521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
153721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1539bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
15440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
15480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
15620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
15650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
15680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
15710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1583bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1585bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1586bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
16078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
16080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16188182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
162316ea139d53d867211d3bb0fa859a83de653f687ecristytypedef struct _PNGErrorInfo
162416ea139d53d867211d3bb0fa859a83de653f687ecristy{
162516ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
162616ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
162716ea139d53d867211d3bb0fa859a83de653f687ecristy
162816ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
162916ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
163016ea139d53d867211d3bb0fa859a83de653f687ecristy} PNGErrorInfo;
163116ea139d53d867211d3bb0fa859a83de653f687ecristy
1632cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
163416ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
163516ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
163616ea139d53d867211d3bb0fa859a83de653f687ecristy
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
164016ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
164116ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
16420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
164316ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
164416ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
164516ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
1646c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy
164716ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1648b989d32f1a878692144c3b76764f931575f22131glennrp    "  libpng-%s error: %s", png_get_libpng_ver(NULL),message);
164916ea139d53d867211d3bb0fa859a83de653f687ecristy
165016ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,message,
165116ea139d53d867211d3bb0fa859a83de653f687ecristy    "`%s'",image->filename);
16520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1653e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
16548371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
16558371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
16568371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1658faa852bad40107edae19405e76a299057668d795glennrp#else
1659faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1660faa852bad40107edae19405e76a299057668d795glennrp#endif
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1663cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
166516ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
166616ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
166716ea139d53d867211d3bb0fa859a83de653f687ecristy
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
167116ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
167216ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
167316ea139d53d867211d3bb0fa859a83de653f687ecristy
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
16760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
167716ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
167816ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
167916ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
168016ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1681b989d32f1a878692144c3b76764f931575f22131glennrp    "  libpng-%s warning: %s", png_get_libpng_ver(NULL),message);
16820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
168316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1688943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#if PNG_LIBPNG_VER >= 10400
1689a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_alloc_size_t size)
1690a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
1691a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_size_t size)
1692a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1694df0d90e1d3bbfa3956818ac7bf43aa0d008020dccristy  (void) png_ptr;
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1701cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17033bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) png_ptr;
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1714edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrpMagick_png_read_raw_profile(png_struct *ping,Image *image,
1715edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   const ImageInfo *image_info, png_textp text,int ii,ExceptionInfo *exception)
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1717bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
17450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
17490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1750f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
17510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
175297f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
175397f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
175497f90e23c85b9c58387880125c29d8c99126f83aglennrp
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
17570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1761edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping,"invalid profile length");
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
17640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17658723e4bcd840478cecfd29891e792edb499cd0e9cristy  profile=BlobToStringInfo((const void *) NULL,length);
17660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1769edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping, "unable to copy profile");
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
17720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
17760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1777bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1783edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp          png_warning(ping, "ran out of profile data");
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
17920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
179916ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProfile(image,&text[ii].key[17],profile,exception);
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
18010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
18040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18232ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp  LogMagickEvent(CoderEvent,GetMagickModule(),
18242ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp     " read_vpag_chunk: found %c%c%c%c chunk",
18252ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp       chunk->name[0],chunk->name[1],chunk->name[2],chunk->name[3]);
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1841bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
18430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1844bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1857fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
1858fd6fd07e58e3d37313bec849313ac6e2b92e3957dirkstatic void read_tIME_chunk(Image *image,png_struct *ping,png_info *info,
1859fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  ExceptionInfo *exception)
1860fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk{
1861fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_timep
1862fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    time;
1863fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
1864fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (png_get_tIME(ping,info,&time))
1865fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
1866fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      char
1867fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        timestamp[21];
1868fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
1869fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      FormatLocaleString(timestamp,21,"%04d-%02d-%02dT%02d:%02d:%02dZ",
1870fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        time->year,time->month,time->day,time->hour,time->minute,time->second);
1871fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      SetImageProperty(image,"png:tIME",timestamp,exception);
1872fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
1873fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk}
1874fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
1875fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1911cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tEXt/Creation Time chunk into the date:create property */
1912cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1916d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  char
1917ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    im_vers[32],
1918ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    libpng_runv[32],
1919ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    libpng_vers[32],
1920ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    zlib_runv[32],
1921ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    zlib_vers[32];
1922d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
192498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    intent, /* "PNG Rendering intent", which is ICC intent + 1 */
1925cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
19274eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1929913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp    number_colors,
1930faa852bad40107edae19405e76a299057668d795glennrp    pass,
1931faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1932faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1933fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp    ping_file_depth,
1934faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1935faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1936faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
19374eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
19384eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
19394eb3931feb349dd87142c78503b779228f3e1a0fglennrp
19404eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
19414eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
19444383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
194598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_cHRM,
194698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_gAMA,
194798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_iCCP,
194898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_sRGB,
19493d627862fb79aad8a20be4f1587f0b8761db441aglennrp    ping_found_sRGB_cHRM,
1950ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_iCCP,
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19530997332e2c35a821b271d6e7473c01c10dc206adcristy  MemoryInfo
19540997332e2c35a821b271d6e7473c01c10dc206adcristy    *volatile pixel_info;
19550997332e2c35a821b271d6e7473c01c10dc206adcristy
195616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
195716ea139d53d867211d3bb0fa859a83de653f687ecristy    transparent_color;
195816ea139d53d867211d3bb0fa859a83de653f687ecristy
195916ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
196016ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
196116ea139d53d867211d3bb0fa859a83de653f687ecristy
1962faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1963faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1964faa852bad40107edae19405e76a299057668d795glennrp
1965faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1966faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1967faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1968faa852bad40107edae19405e76a299057668d795glennrp
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1979faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1980faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1981faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
19824eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
19834eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
1984faa852bad40107edae19405e76a299057668d795glennrp
198516ea139d53d867211d3bb0fa859a83de653f687ecristy  QuantumInfo
198616ea139d53d867211d3bb0fa859a83de653f687ecristy    *quantum_info;
198716ea139d53d867211d3bb0fa859a83de653f687ecristy
1988bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1989756ae430d36380dfab8ca703538f5922f3796351cristy    ping_rowbytes,
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1995bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
199916ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
200339992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2006eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
2007eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
2008eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
200975fc68f33e6e766a22e8ed653c3ed50b0d142827cristy  unsigned char
20100997332e2c35a821b271d6e7473c01c10dc206adcristy    *ping_pixels;
201155b78b53f1e013e0af19565ac04aaa7660d53795cristy
2012629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
2020fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if !defined(PNG_tIME_SUPPORTED)
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
2022fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
2023629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_APNG_SUPPORTED /* libpng was built with APNG patch; */
2024629960f505ebba710ec9b6953a539a21dab176f2glennrp                          /* ignore the APNG chunks */
2025629960f505ebba710ec9b6953a539a21dab176f2glennrp     97,  99,  84,  76, (png_byte) '\0',   /* acTL */
2026629960f505ebba710ec9b6953a539a21dab176f2glennrp    102,  99,  84,  76, (png_byte) '\0',   /* fcTL */
2027629960f505ebba710ec9b6953a539a21dab176f2glennrp    102, 100,  65,  84, (png_byte) '\0',   /* fdAT */
2028629960f505ebba710ec9b6953a539a21dab176f2glennrp#endif
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2032d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
2033d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
2034d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
2035d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
2036d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
2037ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         MagickLibVersionText,32);
2038d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
2039ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         MagickLibAddendum,32);
2040ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
2041d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
2042d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
2043ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
2044ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
2045ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
2046ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
2047ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
2048d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
2049d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
2050ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
2051ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
2052ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
2053ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
2054ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
20552dd1906783a5ece58a6105b4f59239e28b13caddglennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
20562dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "  Enter ReadOnePNGImage()\n"
20572dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "    IM version     = %s\n"
20582dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "    Libpng version = %s",
20592dd1906783a5ece58a6105b4f59239e28b13caddglennrp       im_vers, libpng_vers);
20602dd1906783a5ece58a6105b4f59239e28b13caddglennrp
20612dd1906783a5ece58a6105b4f59239e28b13caddglennrp  if (logging != MagickFalse)
20622dd1906783a5ece58a6105b4f59239e28b13caddglennrp  {
20632dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (LocaleCompare(libpng_vers,libpng_runv) != 0)
2064d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
20652dd1906783a5ece58a6105b4f59239e28b13caddglennrp    LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
20662dd1906783a5ece58a6105b4f59239e28b13caddglennrp        libpng_runv);
2067d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
20682dd1906783a5ece58a6105b4f59239e28b13caddglennrp    LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
20692dd1906783a5ece58a6105b4f59239e28b13caddglennrp        zlib_vers);
20702dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (LocaleCompare(zlib_vers,zlib_runv) != 0)
20712dd1906783a5ece58a6105b4f59239e28b13caddglennrp    {
20722dd1906783a5ece58a6105b4f59239e28b13caddglennrp    LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
20732dd1906783a5ece58a6105b4f59239e28b13caddglennrp        zlib_runv);
20742dd1906783a5ece58a6105b4f59239e28b13caddglennrp    }
20752dd1906783a5ece58a6105b4f59239e28b13caddglennrp  }
2076d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
207725c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
208361b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
208461b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
208561b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
208661b4c957269727a0a2526edc2331881da8346100glennrp    {
208761b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
208861b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
208961b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
209061b4c957269727a0a2526edc2331881da8346100glennrp    }
209161b4c957269727a0a2526edc2331881da8346100glennrp#  endif
209261b4c957269727a0a2526edc2331881da8346100glennrp#endif
209361b4c957269727a0a2526edc2331881da8346100glennrp
209416ea139d53d867211d3bb0fa859a83de653f687ecristy
209516ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info = (QuantumInfo *) NULL;
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2098a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
209998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
2100a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
21012dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "    Before reading:\n"
21022dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "      image->alpha_trait=%d"
21032dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "      image->rendering_intent=%d\n"
21042dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "      image->colorspace=%d\n"
21052dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "      image->gamma=%f",
21062dd1906783a5ece58a6105b4f59239e28b13caddglennrp       (int) image->alpha_trait, (int) image->rendering_intent,
21072dd1906783a5ece58a6105b4f59239e28b13caddglennrp       (int) image->colorspace, image->gamma);
210898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  }
210998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  intent=Magick_RenderingIntent_to_PNG_RenderingIntent(image->rendering_intent);
211098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
21110e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
21120e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
21130e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
21140e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
211516ea139d53d867211d3bb0fa859a83de653f687ecristy  transparent_color.alpha=65537;
21160e319739731741c52a6303723e0c8678a0df5579glennrp
2117913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp  number_colors=0;
2118cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
21194eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
2120cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
2121cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
212298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_cHRM = MagickFalse;
212398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_gAMA = MagickFalse;
212498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_iCCP = MagickFalse;
212598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_sRGB = MagickFalse;
21264b917593e694424be469d250448c05c878663812glennrp  ping_found_sRGB_cHRM = MagickFalse;
2127ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  ping_preserve_iCCP = MagickFalse;
2128ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
212998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
213416ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
213516ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
21363e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
2137cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
2138cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21403e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,&error_info,
2141cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
21470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
21550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21620997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=(MemoryInfo *) NULL;
21630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2164faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2170edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2171868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
2172cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2174edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
21750997332e2c35a821b271d6e7473c01c10dc206adcristy      if (pixel_info != (MemoryInfo *) NULL)
21760997332e2c35a821b271d6e7473c01c10dc206adcristy        pixel_info=RelinquishVirtualMemory(pixel_info);
2177edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
21810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
2183f078e391816b7033081339865c711a5547d6aecadirk        image->columns=0;
21840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2187edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2188edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
2189edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
2190edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
2191edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
2192edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2193868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
2194edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
2195edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
2196edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2197943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
2198a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
2199a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
2200a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
2201a3a5f956194e91458e2789966ad15308e8f3df47glennrp
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2205faa852bad40107edae19405e76a299057668d795glennrp
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
22080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2231e604a757f40a91c286711c49577eeced17ea97adglennrp  {
2232e604a757f40a91c286711c49577eeced17ea97adglennrp    const char
2233e604a757f40a91c286711c49577eeced17ea97adglennrp      *value;
2234e604a757f40a91c286711c49577eeced17ea97adglennrp
2235e604a757f40a91c286711c49577eeced17ea97adglennrp    value=GetImageOption(image_info,"profile:skip");
2236e604a757f40a91c286711c49577eeced17ea97adglennrp
2237e604a757f40a91c286711c49577eeced17ea97adglennrp    if (IsOptionMember("ICC",value) == MagickFalse)
2238e604a757f40a91c286711c49577eeced17ea97adglennrp    {
2239e604a757f40a91c286711c49577eeced17ea97adglennrp
2240e604a757f40a91c286711c49577eeced17ea97adglennrp       value=GetImageOption(image_info,"png:preserve-iCCP");
2241e604a757f40a91c286711c49577eeced17ea97adglennrp
2242e604a757f40a91c286711c49577eeced17ea97adglennrp       if (value == NULL)
2243e604a757f40a91c286711c49577eeced17ea97adglennrp          value=GetImageArtifact(image,"png:preserve-iCCP");
2244e604a757f40a91c286711c49577eeced17ea97adglennrp
2245e604a757f40a91c286711c49577eeced17ea97adglennrp       if (value != NULL)
2246e604a757f40a91c286711c49577eeced17ea97adglennrp          ping_preserve_iCCP=MagickTrue;
2247201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp
2248201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp#if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED)
2249201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp       /* Don't let libpng check for ICC/sRGB profile because we're going
2250201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp        * to do that anyway.  This feature was added at libpng-1.6.12.
2251cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp        * If logging, go ahead and check and issue a warning as appropriate.
2252201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp        */
2253cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp       if (logging == MagickFalse)
2254cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp          png_set_option(ping, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON);
2255201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp#endif
2256e604a757f40a91c286711c49577eeced17ea97adglennrp    }
2257e604a757f40a91c286711c49577eeced17ea97adglennrp#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
2258e604a757f40a91c286711c49577eeced17ea97adglennrp    else
2259e604a757f40a91c286711c49577eeced17ea97adglennrp    {
2260e604a757f40a91c286711c49577eeced17ea97adglennrp       png_set_keep_unknown_chunks(ping, 1, mng_iCCP, 1);
2261e604a757f40a91c286711c49577eeced17ea97adglennrp    }
2262e604a757f40a91c286711c49577eeced17ea97adglennrp#endif
2263e604a757f40a91c286711c49577eeced17ea97adglennrp  }
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
22662ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#if PNG_LIBPNG_VER < 10700 /* Avoid libpng16 warning */
22672ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp  png_set_keep_unknown_chunks(ping, 2, NULL, 0);
22682ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#else
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
22702ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#endif
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22782feb141b6f74ce425fed3272286fab1f50366bb9glennrp#ifdef PNG_SET_USER_LIMITS_SUPPORTED
227909cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  if (PNG_LIBPNG_VER >= 10400)
22802feb141b6f74ce425fed3272286fab1f50366bb9glennrp    /* Limit the size of the chunk storage cache used for sPLT, text,
2281687361928f16a28ea56e200d00e970e68173cc25glennrp     * and unknown chunks.
22822feb141b6f74ce425fed3272286fab1f50366bb9glennrp     */
2283687361928f16a28ea56e200d00e970e68173cc25glennrp    png_set_chunk_cache_max(ping, 32767);
228409cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  endif
22852feb141b6f74ce425fed3272286fab1f50366bb9glennrp#endif
22862feb141b6f74ce425fed3272286fab1f50366bb9glennrp
22879bf97b6c2143eb20c330346b01e82102cc082725glennrp#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
22889bf97b6c2143eb20c330346b01e82102cc082725glennrp    /* Disable new libpng-1.5.10 feature */
22899bf97b6c2143eb20c330346b01e82102cc082725glennrp    png_set_check_for_invalid_index (ping, 0);
22909bf97b6c2143eb20c330346b01e82102cc082725glennrp#endif
22919bf97b6c2143eb20c330346b01e82102cc082725glennrp
2292991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2293991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2294991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2308991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2312faa852bad40107edae19405e76a299057668d795glennrp
2313faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2314faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2315faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2316faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2317faa852bad40107edae19405e76a299057668d795glennrp
2318fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp  ping_file_depth = ping_bit_depth;
2319fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp
23200d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  /* Swap bytes if requested */
23210d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  if (ping_file_depth == 16)
23220d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  {
23230d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp     const char
2324a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp       *value;
2325a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
2326a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     value=GetImageOption(image_info,"png:swap-bytes");
2327a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
2328a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value == NULL)
2329a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        value=GetImageArtifact(image,"png:swap-bytes");
2330a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
2331a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value != NULL)
2332a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        png_set_swap(ping);
23330d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  }
23340d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp
23355830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  /* Save bit-depth and color-type in case we later want to write a PNG00 */
23365830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  {
23375830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      char
23385830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        msg[MaxTextExtent];
23395830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
23405830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_color_type);
23413398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.color-type-orig",msg,exception);
23425830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
23435830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
23443398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.bit-depth-orig",msg,exception);
23455830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  }
23465830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2347faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2348faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2349faa852bad40107edae19405e76a299057668d795glennrp
2350faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2351faa852bad40107edae19405e76a299057668d795glennrp
2352faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2354fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       png_set_packing(ping);
2355fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       ping_bit_depth = 8;
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2357faa852bad40107edae19405e76a299057668d795glennrp
2358faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2360faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
236198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2362176b29a003f11fd934137871d574995319408665cristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2363176b29a003f11fd934137871d574995319408665cristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2364176b29a003f11fd934137871d574995319408665cristy    {
2365176b29a003f11fd934137871d574995319408665cristy      image->rendering_intent=UndefinedIntent;
236698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      intent=Magick_RenderingIntent_to_PNG_RenderingIntent(UndefinedIntent);
2367176b29a003f11fd934137871d574995319408665cristy      (void) ResetMagickMemory(&image->chromaticity,0,
2368176b29a003f11fd934137871d574995319408665cristy        sizeof(image->chromaticity));
2369176b29a003f11fd934137871d574995319408665cristy    }
237098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23742dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG width: %.20g, height: %.20g\n"
23752dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG color_type: %d, bit_depth: %d\n"
23762dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG compression_method: %d\n"
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
23782dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) ping_width, (double) ping_height,
23792dd1906783a5ece58a6105b4f59239e28b13caddglennrp        ping_color_type, ping_bit_depth,
23802dd1906783a5ece58a6105b4f59239e28b13caddglennrp        ping_compression_method,
2381faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
23822dd1906783a5ece58a6105b4f59239e28b13caddglennrp
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2385ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (png_get_valid(ping,ping_info, PNG_INFO_iCCP))
2386ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {
2387ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_iCCP=MagickTrue;
2388ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      if (logging != MagickFalse)
2389ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2390ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG iCCP chunk.");
2391ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    }
2392ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
239398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
239498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
239598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_gAMA=MagickTrue;
239698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
239798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
239898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG gAMA chunk.");
239998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
240098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
240198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
240298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
240398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_cHRM=MagickTrue;
240498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
240598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
240698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG cHRM chunk.");
240798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
240898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2409ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (ping_found_iCCP != MagickTrue && png_get_valid(ping,ping_info,
2410ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      PNG_INFO_sRGB))
241198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
2412ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_sRGB=MagickTrue;
241398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
241498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2415ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG sRGB chunk.");
241698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
241798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2418ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2419e604a757f40a91c286711c49577eeced17ea97adglennrp    if (ping_found_iCCP !=MagickTrue &&
2420ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_sRGB != MagickTrue &&
2421ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info, PNG_INFO_iCCP))
242298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
2423ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_iCCP=MagickTrue;
242498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
242598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2426ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG iCCP chunk.");
242798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
242898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2429faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2434e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2435e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2436e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2437e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2438e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2439e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2440e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2441e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
24500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
2459ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2460e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          profile=BlobToStringInfo(info,profile_length);
2461ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2462e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          if (profile == (StringInfo *) NULL)
2463ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          {
2464ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            png_warning(ping, "ICC profile is NULL");
2465ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            profile=DestroyStringInfo(profile);
2466ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          }
2467ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          else
2468ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          {
2469ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            if (ping_preserve_iCCP == MagickFalse)
2470edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2471ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 int
2472ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
2473ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
2474ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2475ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2476ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 png_uint_32
2477ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   length,
2478ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
2479ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2480ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 unsigned char
2481ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   *data;
2482ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2483ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
2484ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2485ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
2486ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 {
2487ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
2488ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   {
2489ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
2490ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
2491ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2492ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
2493ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                         (unsigned long) length);
2494ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2495ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
2496ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
2497ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2498ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2499ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
2500ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
2501ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
2502ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2503ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
2504ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
2505ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2506ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
2507ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
2508ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
2509ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        if (image->rendering_intent==UndefinedIntent)
2510ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
2511ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
2512ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
2513ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
2514ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
2515ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        break;
2516ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
2517ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   }
2518ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 }
2519ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
2520ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 {
2521ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2522ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
2523ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        (unsigned long) length);
2524ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) SetImageProfile(image,"icc",profile,exception);
2525ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 }
2526edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2527ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            else /* Preserve-iCCP */
2528edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2529ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) SetImageProfile(image,"icc",profile,exception);
2530edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2531ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2532ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            profile=DestroyStringInfo(profile);
2533ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          }
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2537ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2540ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    if (ping_found_iCCP==MagickFalse && png_get_valid(ping,ping_info,
2541ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        PNG_INFO_sRGB))
2542ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {
2543ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      if (png_get_sRGB(ping,ping_info,&intent))
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2545ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        if (image->rendering_intent == UndefinedIntent)
2546ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          image->rendering_intent=
2547ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             Magick_RenderingIntent_from_PNG_RenderingIntent (intent);
25480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2551e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2553ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    }
2554ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2555ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    else if (mng_info->have_global_srgb)
2556ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      {
2557ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        if (image->rendering_intent == UndefinedIntent)
2558ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          image->rendering_intent=
2559ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            Magick_RenderingIntent_from_PNG_RenderingIntent
2560ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            (mng_info->global_srgb_intent);
2561ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      }
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2564ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2565ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2567faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2568faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2569faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
25700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
257998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2580faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2581faa852bad40107edae19405e76a299057668d795glennrp    {
2582faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2583faa852bad40107edae19405e76a299057668d795glennrp        {
2584faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2585faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2586faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2587faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2588faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2589faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2590faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2591faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2592faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2593faa852bad40107edae19405e76a299057668d795glennrp        }
2594faa852bad40107edae19405e76a299057668d795glennrp    }
25950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2596faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
26070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2608ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp       ping_found_cHRM=MagickTrue;
2609ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
26103d627862fb79aad8a20be4f1587f0b8761db441aglennrp       if (image->chromaticity.red_primary.x>0.6399f &&
26113d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
26123d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
26133d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
26143d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
26153d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
26163d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
26173d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
26183d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
26193d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
26203d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
26213d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
26223d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
26233d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
26243d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
26253d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f)
26263d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_sRGB_cHRM=MagickTrue;
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2629e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26313d627862fb79aad8a20be4f1587f0b8761db441aglennrp      if (ping_found_sRGB != MagickTrue &&
26323d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_gAMA != MagickTrue ||
263384288238d90b2e1831857d6b2427abd7875b7e1bglennrp          (image->gamma > .45 && image->gamma < .46)) &&
26343d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_cHRM != MagickTrue ||
2635cd8b331760407523f2a59cc65c1cd9c3d4422bafcristy          ping_found_sRGB_cHRM != MagickFalse) &&
26363d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_iCCP != MagickTrue)
26375cf1bff142633838354b1080183c957900bc80e8glennrp      {
26385cf1bff142633838354b1080183c957900bc80e8glennrp         png_set_sRGB(ping,ping_info,
26395cf1bff142633838354b1080183c957900bc80e8glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent
26405cf1bff142633838354b1080183c957900bc80e8glennrp            (image->rendering_intent));
26415cf1bff142633838354b1080183c957900bc80e8glennrp         file_gamma=1.000f/2.200f;
26425cf1bff142633838354b1080183c957900bc80e8glennrp         ping_found_sRGB=MagickTrue;
264384288238d90b2e1831857d6b2427abd7875b7e1bglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2644918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp           "    Setting sRGB as if in input");
26455cf1bff142633838354b1080183c957900bc80e8glennrp      }
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26475cf1bff142633838354b1080183c957900bc80e8glennrp
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2649faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2651905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2652905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
26530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2657e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2658e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2662faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2663faa852bad40107edae19405e76a299057668d795glennrp    {
2664faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2665faa852bad40107edae19405e76a299057668d795glennrp        {
2666faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2667faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2668faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2669faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2670faa852bad40107edae19405e76a299057668d795glennrp        }
2671faa852bad40107edae19405e76a299057668d795glennrp    }
2672faa852bad40107edae19405e76a299057668d795glennrp
26735c97f62ba919c3c109f0072df3b560056565e9e7cristy  x_resolution=0;
26745c97f62ba919c3c109f0072df3b560056565e9e7cristy  y_resolution=0;
26755c97f62ba919c3c109f0072df3b560056565e9e7cristy  unit_type=0;
2676faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
26820881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
268316ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.x=(double) x_resolution;
268416ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.y=(double) y_resolution;
26850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
268916ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.x=(double) x_resolution/100.0;
269016ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.y=(double) y_resolution/100.0;
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2695e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2696e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2699823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2700faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
27060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2708faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
27140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2715faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2716edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              {
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
2719edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                    png_warning(ping,
2720edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                      "global tRNS has more entries than global PLTE");
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2722edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                else
2723edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  {
2724edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                     png_set_tRNS(ping,ping_info,mng_info->global_trns,
2725edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                       (int) mng_info->global_trns_length,NULL);
2726edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  }
2727edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               }
2728bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2733faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
27353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2742faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2743faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
27440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
27470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
27500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
27530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2754c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2755c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2756c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2762edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"No global PLTE in file");
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2766bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2767faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2768faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
27700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2771faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2773bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2774bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2775bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
27762dd1906783a5ece58a6105b4f59239e28b13caddglennrp      /* Set image background color.
27772dd1906783a5ece58a6105b4f59239e28b13caddglennrp       * Scale background components to 16-bit, then scale
2778bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2779bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
27802cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2781bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
27820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2783fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth == 1)
2784bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
27850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2786fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 2)
2787bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
27880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2789fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 4)
2790bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
27910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2792fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth <= 8)
2793bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
27942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2795bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2796bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2797bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
27982cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2799bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2800bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
28012dd1906783a5ece58a6105b4f59239e28b13caddglennrp            if (logging != MagickFalse)
28022dd1906783a5ece58a6105b4f59239e28b13caddglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28032dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 "    Reading PNG bKGD chunk, raw ping_background=(%d,%d,%d).\n"
28042dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 "    bkgd_scale=%d.  ping_background=(%d,%d,%d).",
28052dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->red,ping_background->green,
28062dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->blue,
28072dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 bkgd_scale,ping_background->red,
28082dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->green,ping_background->blue);
2809bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
28102cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2811bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2812faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
28130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2814bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2815faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
28160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2817bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2818bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
28190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
282016ea139d53d867211d3bb0fa859a83de653f687ecristy        image->background_color.alpha=OpaqueAlpha;
28212cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2822bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2823bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2824bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2825bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2826bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2827bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2829bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2830a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2831faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2834a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
283935ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
284035ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
284135ef824baa82511126ff0072ae30eee0da9c05a3cristy
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2846fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      max_sample = (int) ((one << ping_file_depth) - 1);
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2848faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2849faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2850faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2851faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2852faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2853faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2859faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
28608a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          image->alpha_trait=UndefinedPixelTrait;
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2864a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2865a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2866a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2867fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale_to_short = 65535L/((1UL << ping_file_depth)-1);
2868a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2869a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2870a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2871a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2872a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
287316ea139d53d867211d3bb0fa859a83de653f687ecristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
287405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2875faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28770f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
28780f111984738842d27d04aed2a3f823d82a943506glennrp              {
28790f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28802dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    Raw tRNS graylevel = %d, scaled graylevel = %d.",
28812dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (int) ping_trans_color->gray,(int) transparent_color.alpha);
28820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28830f111984738842d27d04aed2a3f823d82a943506glennrp              }
288416ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.red=transparent_color.alpha;
288516ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.green=transparent_color.alpha;
288616ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.blue=transparent_color.alpha;
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
28883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2893faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2898faa852bad40107edae19405e76a299057668d795glennrp
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2900faa852bad40107edae19405e76a299057668d795glennrp
2901faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2902faa852bad40107edae19405e76a299057668d795glennrp
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2907bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2909bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2912faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2913faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2924faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2925faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2926a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
292716ea139d53d867211d3bb0fa859a83de653f687ecristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
292816ea139d53d867211d3bb0fa859a83de653f687ecristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
29298d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    {
29300a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      double
29310a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp        image_gamma = image->gamma;
29320a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp
29330a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      (void)LogMagickEvent(CoderEvent,GetMagickModule(),
29340a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp         "    image->gamma=%f",(float) image_gamma);
29350a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp
29360a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      if (image_gamma > 0.75)
29378d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        {
29380a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp          /* Set image->rendering_intent to Undefined,
2939e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp           * image->colorspace to GRAY, and reset image->chromaticity.
29408d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp           */
294167429939a9bdca8c2ea541cd690b8e479c921527glennrp          image->intensity = Rec709LuminancePixelIntensityMethod;
29428d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          SetImageColorspace(image,GRAYColorspace,exception);
29438d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        }
2944ccc36af759d30fb50b1deda241d038402a393b17glennrp      else
2945ccc36af759d30fb50b1deda241d038402a393b17glennrp        {
2946ccc36af759d30fb50b1deda241d038402a393b17glennrp          RenderingIntent
2947ccc36af759d30fb50b1deda241d038402a393b17glennrp            save_rendering_intent = image->rendering_intent;
2948ccc36af759d30fb50b1deda241d038402a393b17glennrp          ChromaticityInfo
2949ccc36af759d30fb50b1deda241d038402a393b17glennrp            save_chromaticity = image->chromaticity;
2950ccc36af759d30fb50b1deda241d038402a393b17glennrp
2951ccc36af759d30fb50b1deda241d038402a393b17glennrp          SetImageColorspace(image,GRAYColorspace,exception);
2952ccc36af759d30fb50b1deda241d038402a393b17glennrp          image->rendering_intent = save_rendering_intent;
2953ccc36af759d30fb50b1deda241d038402a393b17glennrp          image->chromaticity = save_chromaticity;
2954ccc36af759d30fb50b1deda241d038402a393b17glennrp        }
2955ccc36af759d30fb50b1deda241d038402a393b17glennrp
2956ccc36af759d30fb50b1deda241d038402a393b17glennrp      image->gamma = image_gamma;
29578d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    }
2958e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
2959e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp  (void)LogMagickEvent(CoderEvent,GetMagickModule(),
29600a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      "    image->colorspace=%d",(int) image->colorspace);
2961a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
2962faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
296332340ffa74550819f755f966e397ed58bbccd8e5glennrp      ((int) ping_bit_depth < 16 &&
296432340ffa74550819f755f966e397ed58bbccd8e5glennrp      (int) ping_color_type == PNG_COLOR_TYPE_GRAY))
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2966befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2967befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2968befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2970befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2971fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      image->colors=one << ping_file_depth;
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
297467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
297567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
297667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
297767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2979faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2985bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
29860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
299816ea139d53d867211d3bb0fa859a83de653f687ecristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
2999edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
30000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3001faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
30070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30086af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30146af6cf1a950b111ad0ac706269a703086693ba71glennrp
301567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
30166af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
30176af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
30186af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
30196af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
30206af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3025bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3028fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale=(QuantumRange/((1UL << ping_file_depth)-1));
30290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
30320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3033bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3041147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3042cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
3043cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
3044147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
3045147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
3046147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3047fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     /* encode ping_width, ping_height, ping_file_depth, ping_color_type,
3048147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
3049147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30503b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,
30517cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
30523398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.width,height",msg,exception);
3053147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3054fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_file_depth);
30553398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.bit_depth",msg,exception);
3056147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30575dff435eceea4f80207a906b11e65aed48fe3f27glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d (%s)",
30585dff435eceea4f80207a906b11e65aed48fe3f27glennrp         (int) ping_color_type,
30595dff435eceea4f80207a906b11e65aed48fe3f27glennrp         Magick_ColorType_from_PNG_ColorType((int)ping_color_type));
30603398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.color_type",msg,exception);
3061147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3062913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (ping_interlace_method == 0)
3063913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3064913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Not interlaced)",
3065913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3066913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3067913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else if (ping_interlace_method == 1)
3068913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3069913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Adam7 method)",
3070913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3071913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3072913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else
3073913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3074913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Unknown method)",
3075913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3076913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3077913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
3078913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp
3079913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (number_colors != 0)
3080913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3081913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d",
3082913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) number_colors);
30833398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:PLTE.number_colors",msg,
3084913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            exception);
3085913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
308639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp   }
3087fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
308839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp   read_tIME_chunk(image,ping,ping_info,exception);
3089fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
309039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
3091147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
30970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30980ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
3099347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
3100347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31021b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
31031b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
31041b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
31051b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3108e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3111edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3112868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3113cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3115edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
31190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
31260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
31280997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(image->rows,ping_rowbytes*
3129cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
31300997332e2c35a821b271d6e7473c01c10dc206adcristy  else
31310997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(ping_rowbytes,sizeof(*ping_pixels));
31320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31330997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
3134edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation failed");
31350997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
31360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31435f766ef8b0cd9906c2c3a56d845828380a251073cristy  quantum_info=AcquireQuantumInfo(image_info,image);
314416ea139d53d867211d3bb0fa859a83de653f687ecristy
314516ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
3146edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping,"Failed to allocate quantum_info");
31470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31484b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
31494b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp
3150c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
3151c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3152c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
3153c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
3154c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3155c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
3156c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3159c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
3160c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3161c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
3162c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
3163c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
3164ccc36af759d30fb50b1deda241d038402a393b17glennrp        image->alpha_trait=
3165ccc36af759d30fb50b1deda241d038402a393b17glennrp            (((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
3166c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
3167c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3168b0a657e13c4aefba39c51292005427b47277869dcristy            BlendPixelTrait : UndefinedPixelTrait;
31690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3170c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
3171c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
3172c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
3173c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
31740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3175c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
3176c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
31770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3178cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
3179c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3180c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          if (pass < num_passes-1)
3181c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp            continue;
3182c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3183862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
318516ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
3186c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
31870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
318816ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
318916ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
319016ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
31910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
319216ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
319316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
319416ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
31950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
319616ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
319716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
319816ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
31990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320016ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
320116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
320216ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
32030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320416ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
320516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
320616ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
32073faa9a3fb01696daaf976d595f492cb530bffb21glennrp
3208c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
3209c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3210c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
3211a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
3212a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3213a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
3214a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3215c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3216c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
32175aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
32185aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
321916ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
3220c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
3221a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3222a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3223a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
3224a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3225c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
3226c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
3227c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
32284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
32294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
323016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
323116ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
323216ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
323316ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
323416ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
323516ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
32364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
3237a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3238a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3239a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
32404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
32414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
32424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
324316ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
3244c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
3245c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
32460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3247af9320404a7b05014476f844b11110157a21b73eglennrp          if (num_passes == 1)
3248c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3249af9320404a7b05014476f844b11110157a21b73eglennrp              status=SetImageProgress(image,LoadImageTag,
3250af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) y, image->rows);
32510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3252c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
3253c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
3254c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
3255c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
3256c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
3257c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
32580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3259af9320404a7b05014476f844b11110157a21b73eglennrp        if (num_passes != 1)
32607a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3261c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
32627a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
32637a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
32647a287bfadeadea12e47c2376ca78a5d101687142cristy          }
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3269c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3281c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3282c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3283c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
328416ea139d53d867211d3bb0fa859a83de653f687ecristy
32858a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
3286b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
32870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
3289b0a657e13c4aefba39c51292005427b47277869dcristy        (image->alpha_trait  == BlendPixelTrait?  2 : 1)*
3290b0a657e13c4aefba39c51292005427b47277869dcristy        sizeof(*quantum_scanline));
32910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
3293edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
32940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3295bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32974f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        Quantum
32984f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp           alpha;
32994f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3301faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3302c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3305c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3306cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
3307c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3308c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp        if (pass < num_passes-1)
3309c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          continue;
3310c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
33114f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
33120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
331316ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
33150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3316cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3318c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3319faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33234f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
3324faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3325bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3327a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33284f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33294f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                alpha=ScaleCharToQuantum((unsigned char)*p++);
33304f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33314f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                SetPixelAlpha(image,alpha,q);
33324f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33334f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                if (alpha != OpaqueAlpha)
33340b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
33354f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
333616ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3340bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3341a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
334547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3348bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3349a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
3350c17d96f447438bb27d874f1440ed05f6493fde1fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
335187281ec8d96ad26dfed9968c29b2920cb3d96744cristy              unsigned short
335258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
335358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
335458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3355c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
335658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
335758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3358c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
335958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
336058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3361c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
336258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
33630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3364faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3366c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3367c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3368c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3369c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3370c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3371c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
33724f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33734f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  alpha=ScaleShortToQuantum(quantum);
33744f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  SetPixelAlpha(image,alpha,q);
33754f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33764f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  if (alpha != OpaqueAlpha)
337758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
33784f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
337916ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
338058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
338158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
338258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
338358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
338458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
338547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
338658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
338758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
338816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
33894f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
339016ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
33910b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
33924f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
339358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
339416ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3397a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
339847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
340147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
34053faa9a3fb01696daaf976d595f492cb530bffb21glennrp
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
34100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
341116ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
341216ea139d53d867211d3bb0fa859a83de653f687ecristy
341316ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
341416ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3415bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
341616ea139d53d867211d3bb0fa859a83de653f687ecristy        {
341716ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
341816ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
341916ea139d53d867211d3bb0fa859a83de653f687ecristy        }
34200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
34230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3424af9320404a7b05014476f844b11110157a21b73eglennrp        if (num_passes == 1)
34257a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3426cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
34279fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
342847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34297a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
34307a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
34317a287bfadeadea12e47c2376ca78a5d101687142cristy          }
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3433c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3434af9320404a7b05014476f844b11110157a21b73eglennrp      if (num_passes != 1)
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
343747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3441c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3444c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3445b0a657e13c4aefba39c51292005427b47277869dcristy    image->alpha_trait=found_transparent_pixel ? BlendPixelTrait :
3446b0a657e13c4aefba39c51292005427b47277869dcristy      UndefinedPixelTrait;
3447c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3448c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3449c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3450c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3451c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3452c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3453c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
34545aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
34555aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34565aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3457bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
34585aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
34595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3462c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
346316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
346416ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
346516ea139d53d867211d3bb0fa859a83de653f687ecristy
34665c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
34675c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3468b0a657e13c4aefba39c51292005427b47277869dcristy      PixelTrait
3469b0a657e13c4aefba39c51292005427b47277869dcristy        alpha_trait;
34705c6f789db7a30bad01ace12b09ad9cd471339e94cristy
3471b0a657e13c4aefba39c51292005427b47277869dcristy      alpha_trait=image->alpha_trait;
34728a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
347316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3474b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait=alpha_trait;
34755c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
347647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34774eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3479ccc36af759d30fb50b1deda241d038402a393b17glennrp  if (logging != MagickFalse)
3480ccc36af759d30fb50b1deda241d038402a393b17glennrp  {
3481ccc36af759d30fb50b1deda241d038402a393b17glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3482ccc36af759d30fb50b1deda241d038402a393b17glennrp       "  image->storage_class=%d\n",(int) image->storage_class);
3483ccc36af759d30fb50b1deda241d038402a393b17glennrp  }
3484ccc36af759d30fb50b1deda241d038402a393b17glennrp
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3486bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
34890997332e2c35a821b271d6e7473c01c10dc206adcristy      pixel_info=RelinquishVirtualMemory(pixel_info);
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
349116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
3492868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3493cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
350047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3501faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
35108a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=BlendPixelTrait;
3511c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35123c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3513c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
35150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3517c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
35180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
35190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35208a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                 image->colormap[x].alpha_trait=BlendPixelTrait;
352116ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
352216ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
35230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3524c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
352547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
35270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
35280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
35290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
353116ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
35320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
35338a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->colormap[x].alpha_trait=BlendPixelTrait;
353416ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
35350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
35360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
35370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
353816ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
35390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
354047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3541a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3542a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3543a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
35440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
35450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
35470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
35480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
35490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3550c11cf6a442f3046940608a5743a68cc891deb13eglennrp
355116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
35520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3553c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3555a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3556a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3557a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
35580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
35590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
356016ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
356116ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
356216ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
356316ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
356416ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
356516ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
35664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
356716ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
35684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
35690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
357067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
35710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
35724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
357316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
35744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3575a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
35760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
357716ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
35780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
35790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
35810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3582c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
35830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3584a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3585c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3589eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
35904eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
35914eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3592a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3593a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
35944eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3595a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3596a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35984eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
35994eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
36004eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
36014eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
36020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36034eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
36044eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36054eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
36060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36075285ae1de367013bf70a5a4e5feaefe3de8dda7bglennrp        if (strlen(text[i].key) > 16 &&
36086dfc26699a1aacdec9771115c4dcaf6c5c0a8f98glennrp            memcmp(text[i].key, "Raw profile type ",17) == 0)
36094eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
361099f968111025b4fadb966ca482c6f57750bf007bglennrp            const char
361199f968111025b4fadb966ca482c6f57750bf007bglennrp              *value;
361299f968111025b4fadb966ca482c6f57750bf007bglennrp
361399f968111025b4fadb966ca482c6f57750bf007bglennrp            value=GetImageOption(image_info,"profile:skip");
361499f968111025b4fadb966ca482c6f57750bf007bglennrp
361599f968111025b4fadb966ca482c6f57750bf007bglennrp            if (IsOptionMember(text[i].key+17,value) == MagickFalse)
361699f968111025b4fadb966ca482c6f57750bf007bglennrp            {
361799f968111025b4fadb966ca482c6f57750bf007bglennrp               (void) Magick_png_read_raw_profile(ping,image,image_info,text,
361899f968111025b4fadb966ca482c6f57750bf007bglennrp                  (int) i,exception);
361999f968111025b4fadb966ca482c6f57750bf007bglennrp               num_raw_profiles++;
362099f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
362199f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
362299f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Read raw profile %s",text[i].key+17);
362399f968111025b4fadb966ca482c6f57750bf007bglennrp            }
362499f968111025b4fadb966ca482c6f57750bf007bglennrp            else
362599f968111025b4fadb966ca482c6f57750bf007bglennrp            {
362699f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
362799f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
362899f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Skipping raw profile %s",text[i].key+17);
362999f968111025b4fadb966ca482c6f57750bf007bglennrp            }
36304eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
36314eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36324eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
36334eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
36344eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
36354eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
36364eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36374eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
36384eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
36394eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
36404eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
36414eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
3642edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"Memory allocation failed");
36434eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
36444eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
36454eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
36464eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
36474eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36484eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
36494eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
36504eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
36514eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
36524eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
36534eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
365416ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36564eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36584eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36592dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      length: %lu\n"
36602dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      Keyword: %s",
36612dd1906783a5ece58a6105b4f59239e28b13caddglennrp                (unsigned long) length,
36622dd1906783a5ece58a6105b4f59239e28b13caddglennrp                text[i].key);
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36654eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
366697f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
36674eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
3668fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    num_text_total += num_text;
3669fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
36703c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
368373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
36840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
369147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
3696edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp             png_error(ping,"Memory allocation failed");
36970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
3699edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping,"Cannot overwrite frozen MNG object buffer");
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
37080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
371016ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
37110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
37140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
3716edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping, "Cloning image for object buffer failed");
37170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3718faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
37200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3721faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3722faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3723faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3724faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3725faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3726faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3727faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3728faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
37290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3730faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
37403c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
374647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37520a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
37538a46d827a124555f0c48fb2368ec1bba8e079ab6cristy   /* Set image->alpha_trait to MagickTrue if the input colortype supports
37540a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
37550a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
37560a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
37578a46d827a124555f0c48fb2368ec1bba8e079ab6cristy    image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
37580a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
37590a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3760b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
37610a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3762224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#if 0  /* I'm not sure what's wrong here but it does not work. */
376317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy    if (image->alpha_trait != UndefinedPixelTrait)
37645830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37655830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
37665830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleMatteType,exception);
37675830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37685830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
37695830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteMatteType,exception);
37705830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37715830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
37725830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
37735830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
37745830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37755830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    else
37765830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37775830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
37785830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleType,exception);
37795830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37805830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
37815830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteType,exception);
37825830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37835830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
37845830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorType,exception);
37855830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
3786224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#endif
37875830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
3788cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3789cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3790cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3791cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3792cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
37934eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3794cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3795cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
37963b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3797613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
37983398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:text",msg,
379916ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3800cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3801cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3802cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3803cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
38043b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3805cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
380616ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
380716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3808cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3809cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
381098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_cHRM != MagickFalse)
38115961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
38123b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38135961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
38143398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:cHRM",msg,
381516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38165961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3817cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3818cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
38195961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
38203b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38215961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
38223398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:bKGD",msg,
382316ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38245961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
38255961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
38263b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38275961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3828cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
382998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#if defined(PNG_iCCP_SUPPORTED)
383098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_iCCP != MagickFalse)
38313398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:iCCP",msg,
383216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
383398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#endif
3834cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38354eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
38363398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:tRNS",msg,
383716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38384eb3931feb349dd87142c78503b779228f3e1a0fglennrp
38394eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
384098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_sRGB != MagickFalse)
38414eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38423b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
384398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            "intent=%d (%s)",
384498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            (int) intent,
384598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            Magick_RenderingIntentString_from_PNG_RenderingIntent(intent));
38463398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:sRGB",msg,
384798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp                 exception);
38484eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38494eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38504eb3931feb349dd87142c78503b779228f3e1a0fglennrp
385198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_gAMA != MagickFalse)
38524eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38533b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
385416ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
385516ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
38563398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:gAMA",msg,
385716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38584eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3859cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38604eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3861cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
38624eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38633b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
386407523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
38654eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
38663398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:pHYs",msg,
386716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38684eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38694eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3870cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38714eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
38724eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
38734eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38743b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
38754eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
38763398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:oFFs",msg,
387716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38784eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38794eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38804eb3931feb349dd87142c78503b779228f3e1a0fglennrp
3881fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
3882fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk     read_tIME_chunk(image,ping,end_info,exception);
3883fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
3884fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
388507523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
388607523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
388707523c7d2e40370804c2036295571e4b6426f94dglennrp       {
38883b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
388907523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
389007523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
38913398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:vpAg",msg,
389216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
389307523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3894cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3895cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39010997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
39060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3907868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3908edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
3909edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
3910edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3911edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* }  for navigation to beginning of SETJMP-protected block, revert to
3912edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    Throwing an Exception when an error occurs.
3913edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
3914edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
3923919429921a43880a338ed87e128d3b96219442efglennrp    *image;
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
392621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
392721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
394447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
394847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3951fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
395216ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
395547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
395847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
396347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3964dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
396647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
397173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
397247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
397547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
398547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
39910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
399447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
399647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
40020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
400547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
400672715f5c299a6482f8eb175070b056d77b74a43fcristy  if ((IssRGBColorspace(image->colorspace) != MagickFalse) &&
40073d627862fb79aad8a20be4f1587f0b8761db441aglennrp      ((image->gamma < .45) || (image->gamma > .46)) &&
40083d627862fb79aad8a20be4f1587f0b8761db441aglennrp           !(image->chromaticity.red_primary.x>0.6399f &&
40093d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
40103d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
40113d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
40123d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
40133d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
40143d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
40153d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
40163d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
40173d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
40183d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
40193d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
40203d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
40213d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
40223d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
40233d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f))
4024ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4025ccc36af759d30fb50b1deda241d038402a393b17glennrp       SetImageColorspace(image,RGBColorspace,exception);
4026ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
402772715f5c299a6482f8eb175070b056d77b74a43fcristy
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
4029ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4030ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4031ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
4032ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.width,(double) image->page.height,
4033ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.x,(double) image->page.y);
4034ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4035ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  image->colorspace: %d", (int) image->colorspace);
4036ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
403797f90e23c85b9c58387880125c29d8c99126f83aglennrp
403897f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
40400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40924383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
40934383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
40944383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
4095bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
411516ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4118bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
412216ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
4130e0421fec74bee9a6f9def3d51aed4204f970ad73glennrp    reading_idat;
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4132bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
4146fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
41490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
415016ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
41580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
415916ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
41600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
41630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
41900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
41930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4201e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
4202e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
42056af512ae5eeeed8effd9af4d57aab7caf74c65eddirk      ThrowReaderException(CorruptImageError,"CorruptImage");
42060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
420947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42108fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
42130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4217bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
42190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
422247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
4230e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[2] << 8) | p[3]);
4231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
4232e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[6] << 8) | p[7]);
4233e2440c250d94d64f8c70e596fe90808795aaa07ecristy            if ((jng_width == 0) || (jng_height == 0))
4234e2440c250d94d64f8c70e596fe90808795aaa07ecristy              ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
423947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
424247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
424747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42512dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_width:      %16lu,    jng_height:     %16lu\n"
42522dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_color_type: %16d,     jng_image_sample_depth: %3d\n"
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
42542dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (unsigned long) jng_width, (unsigned long) jng_height,
42552dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_color_type, jng_image_sample_depth,
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
425747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42592dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_image_interlace_method:  %3d"
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
42612dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_image_interlace_method,
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
426347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42652dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_compression_method:%3d\n"
42662dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_filter_method:     %3d\n"
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
42682dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_compression_method,
42692dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_filter_method,
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
427347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42748fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
427647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
429273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
429347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
429647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
429816ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
42990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
43060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
43100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
431773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
43180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
432316ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
43240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
43350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
43390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
43420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
43510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
43540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
435703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
437447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
438147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43828fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
438447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
439347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4401bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
440303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44108fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
441847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44298fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
44380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44398fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
44688182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
44690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44788182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
44798182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
44808182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
44818182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
44828182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
44838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
44848182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
44858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
448747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4496e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4497cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
4498da7803d6b1161960bc1e7db4d9718284c116fab8cristy            image->gamma=1.000f/2.200f;
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
450847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45175eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
45185eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
45190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
452647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45278fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
453716ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
453816ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
454216ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
454316ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4554fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
45558fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45628fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
45670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
459016ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
459647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
46000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4601f0eec7524321f1be1bfe568a13ab7d4d0333c814cristy  assert(color_image_info != (ImageInfo *) NULL);
46023b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
46040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
46070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
46210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
46240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4625bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
462716ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
462916ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
463016ea139d53d867211d3bb0fa859a83de653f687ecristy    {
463116ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
463216ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
463316ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
463416ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
463516ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
463616ea139d53d867211d3bb0fa859a83de653f687ecristy    }
463747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
46410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
46430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
465403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
46580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
46600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
466316ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46653b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
46690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4671bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
467416ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
467647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
467717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy             if (image->alpha_trait != UndefinedPixelTrait)
467816ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
467916ea139d53d867211d3bb0fa859a83de653f687ecristy               {
468016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
468116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
468216ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
468316ea139d53d867211d3bb0fa859a83de653f687ecristy               }
46840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
468616ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
468816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
468916ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
46908a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->alpha_trait=BlendPixelTrait;
469116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
469216ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
46940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
470647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
470747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
47150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
47170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
47180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
47210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
47230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
47270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
47340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
47380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
47767ee973a2149db53911459cbf26f28eccdbc99efbglennrp    *image;
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
477921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
478021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4800fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
480116ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
48040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
48070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
481147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
481247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
481447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48153b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
481847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
481947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
482173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
48220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
48250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
482647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
482747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
48340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
484447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
48560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48704383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
487121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
487221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
48734383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4880bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
489816ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4905bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4911bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4928bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
493738ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
493838ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
493938ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4940bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
496247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
496347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4969fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
497016ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
49730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
49760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
498047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
498147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
498247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
498373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
49840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
49870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
498847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
498947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
499947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
500347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
500447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5007bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
5008bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
501247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5055e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
5056e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
50600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
50630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
50660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50678fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
507047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
507347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5074bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
507647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
50860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
508816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
50900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
50970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
509916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
51010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
510647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
51110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51128fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
51180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5124bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
51260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5127bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
51290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5133e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5135e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
51398182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
51400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
51430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
51470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
51500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
51548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
51580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
51610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
51640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
516916ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
517147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
517216ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
51730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
51760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
51840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51853b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy            (void) FormatLocaleString(page_geometry,MaxTextExtent,
5186e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
5187f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
51880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
5190bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
5192bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
51940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
51970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52088fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
52100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
52148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
52150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
52180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5226280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  "    repeat=%d,  final_delay=%.20g,  iterations=%.20g",
5227280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  repeat,(double) final_delay, (double) image->iterations);
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
523616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
52410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
524316ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
5250edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  Instead of using a warning we should allocate a larger
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
525316ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
526216ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
52680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
52700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
52730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
52800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
52810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
52830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
52840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5288280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      "  x_off[%d]: %.20g,  y_off[%d]: %.20g",
5289280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->x_off[object_id],
5290280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->y_off[object_id]);
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
53000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
53070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
53300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
53330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
534516ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
535647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
535947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
536047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
53660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5367bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
537435ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
53830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53848fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
53890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
539347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5399bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
540612560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5414bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54178182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
54240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
543147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
543247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54358182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
54368182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
54378182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
54398182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
54418182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
54438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
54458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
54478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
545247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
545647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54628fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5464e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5465cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
547047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
547447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5477fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54828fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
548447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
548747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
549116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
54940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
54970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
550147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55028fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
55050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
55090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
551247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
551347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
551547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5516bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
551847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
552047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5521bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
553247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55358182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
55368182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
55370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55388182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
55398182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
55400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5541bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5542bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
55430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
55460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5551e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
555347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5556bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5557bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
55580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5559bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5560bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
55610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5562bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5563bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
55640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
55670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5572e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
557447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
55800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5584e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5585e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
558647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
55940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5595bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
55970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5598bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5606e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5607e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
56080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
561247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
561316ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
561516ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
561647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
562347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
56280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
56380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
56468a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                image->alpha_trait=UndefinedPixelTrait;
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
564816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
56490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5653e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5654e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
567147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
568347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56998fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
570747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
570847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5717bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5720bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57278fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
573247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
573947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
574047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5743bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
576047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
577047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
577147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
57728182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
57730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5776e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5777e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
57780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
57810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
579247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
579647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
580847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
58150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5819e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5820f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
582147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
58260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
583147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
584947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
585347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
585716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
586047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
586347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
58800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
58830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
58860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
589316ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
589747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
590347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
590947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
591247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
591847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
592147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
592747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
593047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
593647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
593947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
594547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
594847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
595447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
595747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
596347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
596747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
597116ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
597547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
599447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
599816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
600147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
600447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
600816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
601147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
601447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
601947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
60358182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
60378182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
604147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
604816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
605047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
605647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
605816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
606147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
6064bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
6066bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
607447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
607747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
608047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
608347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
608647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
608947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
609247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
610047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
610347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
610647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
611147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
61198fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
612147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
612847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
613147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
613747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
614547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
61478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
6160bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
6162bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
616416ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
616916ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
617047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
617747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
618147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
618847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
619147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
619247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
619347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
620216ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6205e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
6206e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
621716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
622216ea139d53d867211d3bb0fa859a83de653f687ecristy              AcquireNextImage(image_info,image,exception);
622347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
623047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
62330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
62350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
624547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
62548a46d827a124555f0c48fb2368ec1bba8e079ab6cristy            image->alpha_trait=UndefinedPixelTrait;
625516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
62560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6260e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6261e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
626547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
626616ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
627116ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
627247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
627947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
62850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
62880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
62970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
63060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
631247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
631647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
632147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6322bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
632347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
633547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
634847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
638147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
638447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
638647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
638747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
638947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63924e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
639347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
639647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
639947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
640147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
640247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
640447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
640847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
641147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
641347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
641447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
641647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64194e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
642047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
642347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
642647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
642847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
642947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
643147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
644116ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
644216ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
644316ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
644416ea139d53d867211d3bb0fa859a83de653f687ecristy
644516ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
644616ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
644716ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
644816ea139d53d867211d3bb0fa859a83de653f687ecristy
6449bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
645316ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
645716ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
645816ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
646047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
646147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
646547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
646616ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
646747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64833faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6491bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
649547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6496bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
649816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
649916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
650016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
650116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
650216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
650316ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
650416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
650516ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
650616ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
650847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
651717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                if (image->alpha_trait != UndefinedPixelTrait)
651816ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
651947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
652216ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
652316ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
652447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
652747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
653047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
653347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6542e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6543bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
65454f7c434c6c7047588b48a5b71281f9ecf4c9d1accristy                length=(size_t) GetPixelChannels(image)*image->columns;
654616ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
654716ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
654847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
654916ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
655016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
655747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
656047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6564bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
656547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6566bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6567bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
656847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6569bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6570bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
657147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6572bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
657447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6576bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
657747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
658147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
658847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
659116ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
65989fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
659916ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
660016ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
660147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6604fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6613bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
661416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
661516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
661616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
661716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
661816ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
661916ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
662016ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
662247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6626bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
662716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
662816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
662916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
663016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
663116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
663216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
663316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
663416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6635bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
663647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
664016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
664116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
664216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6643bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
664416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
664516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
664616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
664716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6648bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
664916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
665016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
665116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
665216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6653bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
665416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
665547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
665617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                              if (image->alpha_trait != UndefinedPixelTrait)
665716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
665816ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
665916ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6660bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
666116ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
666347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
666816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
666916ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
667116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
667216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
667547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6680bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
668116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
668216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
668316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
668416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
668516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
668616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
668716ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
668816ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6689bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
669047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6692bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
669316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
669416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
669516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
669616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
669716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
669816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
669916ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6700bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
670147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
670416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
670516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
670616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6707bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
670816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
671116ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
671216ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
671316ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
671547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
671847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
672147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
672216ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
672316ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6740e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6742bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
674416ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
674816ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
674916ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
675047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6751bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6752bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
675416ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
67557c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6756bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6757bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
675847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6759bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6760bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
676147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6762bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6763bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
676447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6765bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
676747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6769bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
677047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
677616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
677716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
677816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
677916ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
678147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6785bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
678616ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
678716ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
678816ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
678916ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6790bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
679147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
679216ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
679616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
679716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
679816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6799bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
680016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6801bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
680216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
680316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
680416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6805bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
680616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6807bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
680816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
680916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
681016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6811bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
681216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
681317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                              if (image->alpha_trait != UndefinedPixelTrait)
681416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
681516ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
681616ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6817bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
681816ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
682047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6825bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
682616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
682716ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6828bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6830bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
683116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
683216ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6833bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
683647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6841bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
684216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
684316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
684416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
684516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6846bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
684747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6849bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
685016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
685116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
685216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
685316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6854bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
685547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
685916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
686016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
686116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6862bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
686316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
686616ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
686816ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
687047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68743faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6880bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
688347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6884bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
688616ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
688716ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
688816ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
688916ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
689016ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
689116ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
689216ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
689316ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
689416ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
689647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
693047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6946bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6947bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
695347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
696547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
697616ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69882b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69892b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
699016ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
69912b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
69922b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
69932b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
69942b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
69952b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
69963faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
6997cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
6998cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
6999cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
7000cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
7001cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
7002cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
700316ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
70048640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7006d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
7010bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7013d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
7017d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
701947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
702147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
702547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
70360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
703716ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
704216ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
704747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
705147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
70638a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
70640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
706616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
70670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
70720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
70750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
708347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
708416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
708747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
70920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
709747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
709816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
710347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
711147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
711216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
71153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
711647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
712247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
712316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
712547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
712847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
71360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
71390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
71420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
714747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
71530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
71550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7158e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
7159e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
71600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
716847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
717147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7173e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
717447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7179e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7191bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
719647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
719816ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
719947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
720247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
720547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
721447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
721747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
723447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
724447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
724747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7249e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
7250e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
725147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7253f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7254f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
725547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7256f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7257e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7258e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7259f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7260f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
726147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
726547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
726847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
727125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
727647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
727947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
728247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
728725c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7310bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7313bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
732647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
733247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
734047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
734447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
735247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
735547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
736047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
736347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
736647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7367afc97b1e31b78c973c4bf5e0be8d5090cfca8065glennrp  entry->mime_type=ConstantString("video/x-mng");
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
737347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
737847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
7382d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
738447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
738747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
739247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
739747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
7402d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
740847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
741247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
741947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
742247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
742747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
7430fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or binary transparent 24-bit RGB");
7431d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
743647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
744147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
7445d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7449fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry=SetMagickInfo("PNG48");
7450fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7451fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7452fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7453fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7454fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7455fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7456fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
7457fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->adjoin=MagickFalse;
7458fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or binary transparent 48-bit RGB");
7459d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7460fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->module=ConstantString("PNG");
7461fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7462fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7463fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry=SetMagickInfo("PNG64");
7464fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7465fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7466fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7467fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7468fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7469fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7470fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
7471fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->adjoin=MagickFalse;
7472fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or transparent 64-bit RGBA");
7473d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7474fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->module=ConstantString("PNG");
7475fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7476fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
74775830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry=SetMagickInfo("PNG00");
74785830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
74795830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
74805830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74815830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74825830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#endif
74835830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
74845830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
74855830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->adjoin=MagickFalse;
74866270857991c1a3fb1d05e652e81835ee4fcf0a34glennrp  entry->description=ConstantString(
74876270857991c1a3fb1d05e652e81835ee4fcf0a34glennrp    "PNG inheriting bit-depth and color-type from original");
7488d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74895830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->module=ConstantString("PNG");
74905830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) RegisterMagickInfo(entry);
74915830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
749347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
750047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
75047fee329aec1090ff832c1b07fc4cc70c3b604f65glennrp  entry->mime_type=ConstantString("image/x-jng");
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
750847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7509868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
75103d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy  ping_semaphore=AcquireSemaphoreInfo();
751118b17443128598500357da7bff2f01683cf32890cristy#endif
751247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
7542fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG48");
7543fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG64");
75445830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) UnregisterMagickInfo("PNG00");
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
754647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7547868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
7548cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
75493d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy    RelinquishSemaphoreInfo(&ping_semaphore);
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
755425c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
757316ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
757416ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
758216ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7632cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
76600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
76610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
76630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7664ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7665a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
7666a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7667a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
7668a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
7672ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7673a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping,
7674a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy      (png_alloc_size_t) allocated_length);
7675a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
7676a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7677a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
7678a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
7679a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
76843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
76913b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7692f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
769447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7695bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
770247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
770947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
771247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7718cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
77194383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
773347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
773447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
773547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
773747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7741cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
774347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
774447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
774547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
774647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
774747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
774847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7749cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7750cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7751cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
775247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
775347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
775447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
775547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
775647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
775747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
775847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7759cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
776047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
776247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
776547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
77673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7769fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
7770fd6fd07e58e3d37313bec849313ac6e2b92e3957dirkstatic void write_tIME_chunk(Image *image,png_struct *ping,png_info *info,
7771fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  const char *date,ExceptionInfo *exception)
7772fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk{
7773fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  unsigned int
7774fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    day,
7775fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    hour,
7776fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    minute,
7777fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    month,
7778fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    second,
7779fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    year;
7780fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7781fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_time
7782fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ptime;
7783fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7784fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  time_t
7785fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ttime;
7786fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7787fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (date != (const char *) NULL)
7788fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
7789fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      if (sscanf(date,"%d-%d-%dT%d:%d:%dZ",&year,&month,&day,&hour,&minute,
7790fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          &second) != 6)
7791fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
7792fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
7793fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            "Invalid date format specified for png:tIME","`%s'",
7794fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            image->filename);
7795fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          return;
7796fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
7797fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.year=(png_uint_16) year;
7798fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.month=(png_byte) month;
7799fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.day=(png_byte) day;
7800fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.hour=(png_byte) hour;
7801fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.minute=(png_byte) minute;
7802fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.second=(png_byte) second;
7803fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
7804fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  else
7805fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  {
7806fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    time(&ttime);
7807fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    png_convert_from_time_t(&ptime,ttime);
7808fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
7809fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_set_tIME(ping,info,&ptime);
7810fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk}
7811fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
7812b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7813b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
78143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
781516ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
78163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
78170997332e2c35a821b271d6e7473c01c10dc206adcristy  char
78180997332e2c35a821b271d6e7473c01c10dc206adcristy    im_vers[32],
78190997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_runv[32],
78200997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_vers[32],
78210997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_runv[32],
78220997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_vers[32];
78230997332e2c35a821b271d6e7473c01c10dc206adcristy
782416ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
782516ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
782616ea139d53d867211d3bb0fa859a83de653f687ecristy
782716ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
782816ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
782916ea139d53d867211d3bb0fa859a83de653f687ecristy
78303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
78313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
78343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
78363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
78393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
78403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7843cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7844cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7845e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7846e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
78475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
784839992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
784939992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
78525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
78535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
78545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
78553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
78573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
78593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
78603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
78625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
78635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
78645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7865bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
78663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
78673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
786958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
787021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
787158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
787258e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7873da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7874fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7875d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
78768d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
787739992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7878991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7879918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_iCCP,
7880991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7881918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_sRGB,
7882991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
788326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
788426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
788526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7886a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7887e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
788826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
788926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
789026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
789126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
789226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
789326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
789426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7895fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_exclude_tIME,
7896e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
789726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
789826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
789926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
790026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
79018d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
7902ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_iCCP,
79030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
79040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
790582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
79068ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7907d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7908d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79100997332e2c35a821b271d6e7473c01c10dc206adcristy  MemoryInfo
7911af1534a4abd2d6ef7f7e2833b95400301faff3d3cristy    *volatile pixel_info;
79120997332e2c35a821b271d6e7473c01c10dc206adcristy
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
791616ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
791716ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
791816ea139d53d867211d3bb0fa859a83de653f687ecristy
7919bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
79203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
79223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
79240997332e2c35a821b271d6e7473c01c10dc206adcristy    *ping_pixels;
7925d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
79265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7927f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
79280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
79295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
79305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
79315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
79325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
79335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
79345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7935bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
79365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
79375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7939bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
79403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
79423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
79433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7944dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7945fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7946f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
79478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
79488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
79498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7950dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7951dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7952dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7953dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7954dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7955dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7957fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
795916ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
796016ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
796116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
796216ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7963b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7964d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
7965d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
7966d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
7967d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
7968d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
7969d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp         MagickLibVersionText,MaxTextExtent);
7970d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
7971d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp         MagickLibAddendum,MaxTextExtent);
7972ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7973d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
7974d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
7975ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
7976ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
7977ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
7978ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
7979ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7980d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
7981d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
7982ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
7983ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
7984ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
7985ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
7986ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
79878fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (logging != MagickFalse)
7988d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
7989d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    IM version     = %s",
7990d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           im_vers);
7991d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Libpng version = %s",
7992d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           libpng_vers);
7993ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(libpng_vers,libpng_runv) != 0)
7994ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
7995ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
7996ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           libpng_runv);
7997ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
7998d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
7999d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           zlib_vers);
8000ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(zlib_vers,zlib_runv) != 0)
8001ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8002ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8003ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           zlib_runv);
8004ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8005d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
8006d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
80075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
80080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
80095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
80105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
80115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
80125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
80135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
80145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
80165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
80175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
80185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
80195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
80205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
80225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
80235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
80245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
80255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
8026dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
8027dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
8028dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
8029dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8030da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
8031f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp  ping_have_cheap_transparency=MagickFalse;
8032d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
80338d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
803439992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
8035991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
8036918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_iCCP=MagickFalse;
8037991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
8038918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_sRGB=MagickFalse;
8039991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
8040991d11dd9c33e65872778b81aff1347cd2878154glennrp
80410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
80420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
8043a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
8044dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
80450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
80460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
80470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
80480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
80490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
80500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
80510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
8052fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  ping_exclude_tIME=mng_info->ping_exclude_tIME;
8053dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
80540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
80550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
80560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
80570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
80588d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
8059ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  ping_preserve_iCCP = mng_info->ping_preserve_iCCP;
80600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
80610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
80620d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
80630d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
80640d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
80650d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
80660d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
8067ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8068ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * To do: recognize other variants of the sRGB profile, using the CRC to
8069ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * verify all recognized variants including the 7 already known.
8070ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8071ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Work around libpng16+ rejecting some "known invalid sRGB profiles".
8072ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8073ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Use something other than image->rendering_intent to record the fact
8074ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * that the sRGB profile was found.
8075ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8076ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Record the ICC version (currently v2 or v4) of the incoming sRGB ICC
8077ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * profile.  Record the Blackpoint Compensation, if any.
80780d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
8079ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   if (ping_exclude_sRGB == MagickFalse && ping_preserve_iCCP == MagickFalse)
80800d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
80810d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
80820d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
80830d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80840d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
80850d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
80860d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80870d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
80880d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
80890d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
80900d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
80910d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80920d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
80930d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
80940d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
8095ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                (LocaleCompare(name,"ICM") == 0))
8096ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
8097ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             {
8098ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
8099ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
8100ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
81010d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81020d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8103ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
8104ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
8105ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
810629a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8107ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
8108ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
81090d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8110ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
811129a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8112ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
811329a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
8114ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
8115ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
8116ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
8117ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
8118ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8119ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
8120ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
81210d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8122ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
8123ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
81240d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8125ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8126ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
8127ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
8128ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
8129ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
8130ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
8131ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
8132ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8133ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
8134ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
8135ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
8136ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
8137ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
8138ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
8139ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
8140ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
8141ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
8142ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_iCCP = MagickTrue;
8143ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_zCCP = MagickTrue;
8144ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_have_sRGB = MagickTrue;
8145ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
8146ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
814729a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
81480d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
8149ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
815029a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8151ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
815229a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
815329a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
81540d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
81550d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
81560d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
81570d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
81580d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
81608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
81618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
81628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8163fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
8164fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8165fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
8166fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8167f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=UndefinedClass");
8168fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
8169fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8170f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=DirectClass");
8171fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
8172fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8173f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=PseudoClass");
8174f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(), image->taint ?
8175cc96f2d3d09f91c9333d05e2e7216d4006f8a5eaglennrp          "    image->taint=MagickTrue":
8176cc96f2d3d09f91c9333d05e2e7216d4006f8a5eaglennrp          "    image->taint=MagickFalse");
8177fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
817828af3713c9111a471cc868c787760de89236fa3cglennrp
8179750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  if (image->storage_class == PseudoClass &&
81807e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
8181fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png48 || mng_info->write_png64 ||
8182fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     (mng_info->write_png_colortype != 1 &&
8183fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png_colortype != 5)))
81847e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
818516ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
81867e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
81877e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
81887e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
8189c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
819028af3713c9111a471cc868c787760de89236fa3cglennrp    {
8191c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
8192c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
8193c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
8194c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
8195c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8196c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
8197e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
8198c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
8199c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
820028af3713c9111a471cc868c787760de89236fa3cglennrp    }
8201bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8202c28acd632b7ea1724a54191d15db932f2e4d25e6glennrp  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
820316ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
82040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82053241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
82063241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
82073241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
82083241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
82093241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
821016ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
82113241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8212a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
8213a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
8214a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
8215a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
8216a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8217a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
8218a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8219a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
8220a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
8221a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
8222a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
82238e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
8224cd979955e4249aab3bdd79043718fa3b120239b8dirk  if (image->depth < 4)
822567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
822616ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
82278e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
82288e58efdecda887b08ef730d68290a61081ef2566glennrp
8229aac49630945ded4a68aca4f7c892e18b21afeba8dirk       if (image->depth > 2)
82308e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82318e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
823291d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
82338e58efdecda887b08ef730d68290a61081ef2566glennrp
82348e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82358e58efdecda887b08ef730d68290a61081ef2566glennrp           {
823616ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82378e58efdecda887b08ef730d68290a61081ef2566glennrp
823816ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82398e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82408e58efdecda887b08ef730d68290a61081ef2566glennrp
82418e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82428e58efdecda887b08ef730d68290a61081ef2566glennrp             {
824316ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
824416ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82458e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8246bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82478e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82488e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82498e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82508e58efdecda887b08ef730d68290a61081ef2566glennrp
82518e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82528e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82533e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82548e58efdecda887b08ef730d68290a61081ef2566glennrp             {
825591d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
82568e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82578e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82588e58efdecda887b08ef730d68290a61081ef2566glennrp         }
82598e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
82608e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82618e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
826291d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
82638e58efdecda887b08ef730d68290a61081ef2566glennrp
82648e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82658e58efdecda887b08ef730d68290a61081ef2566glennrp           {
826616ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82678e58efdecda887b08ef730d68290a61081ef2566glennrp
826816ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82698e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82708e58efdecda887b08ef730d68290a61081ef2566glennrp
82718e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82728e58efdecda887b08ef730d68290a61081ef2566glennrp             {
827316ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
827416ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82758e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8276bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82778e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82788e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82798e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82808e58efdecda887b08ef730d68290a61081ef2566glennrp
82818e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82828e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82833e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82848e58efdecda887b08ef730d68290a61081ef2566glennrp             {
828591d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
82868e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82878e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82888e58efdecda887b08ef730d68290a61081ef2566glennrp         }
82898e58efdecda887b08ef730d68290a61081ef2566glennrp       else
82908e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82918e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
829291d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
82938e58efdecda887b08ef730d68290a61081ef2566glennrp
82948e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82958e58efdecda887b08ef730d68290a61081ef2566glennrp           {
829616ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82978e58efdecda887b08ef730d68290a61081ef2566glennrp
829816ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82998e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
83008e58efdecda887b08ef730d68290a61081ef2566glennrp
83018e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
83028e58efdecda887b08ef730d68290a61081ef2566glennrp             {
830316ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
830416ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
83058e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8306bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
83078e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
83088e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
83098e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83108e58efdecda887b08ef730d68290a61081ef2566glennrp
83118e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83128e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83133e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83148e58efdecda887b08ef730d68290a61081ef2566glennrp             {
831591d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
83168e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83178e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83188e58efdecda887b08ef730d68290a61081ef2566glennrp         }
8319cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
8320cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
832167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
832267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
832370e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
8324a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
83252b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
83262b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
83272b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
83282b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
83298e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
83302b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
83312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
83322b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83333faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
8334cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
8335cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
8336cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
8337cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
8338cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
8339cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
8340c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
834116ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
83428640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
83438640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
83448640fb5e9b1094f35f8beab436f81661b8a99448glennrp
8345d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  image_colors = (int) image->colors;
8346d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_opaque = (int) image->colors;
8347d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_transparent = 0;
8348d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_semitransparent = 0;
8349d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
8350197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  if (mng_info->write_png_colortype &&
8351a8036d6466b63ead629795b60772f160cca77c4cglennrp     (mng_info->write_png_colortype > 4 || (mng_info->write_png_depth >= 8 &&
8352a8036d6466b63ead629795b60772f160cca77c4cglennrp     mng_info->write_png_colortype < 4 &&
835317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     image->alpha_trait == UndefinedPixelTrait)))
8354a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8355a8036d6466b63ead629795b60772f160cca77c4cglennrp     /* Avoid the expensive BUILD_PALETTE operation if we're sure that we
8356a8036d6466b63ead629795b60772f160cca77c4cglennrp      * are not going to need the result.
8357a8036d6466b63ead629795b60772f160cca77c4cglennrp      */
8358a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (mng_info->write_png_colortype == 1 ||
8359a8036d6466b63ead629795b60772f160cca77c4cglennrp        mng_info->write_png_colortype == 5)
8360a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickFalse;
8361a8036d6466b63ead629795b60772f160cca77c4cglennrp
836217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     if (image->alpha_trait != UndefinedPixelTrait)
8363a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8364a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 2;
8365a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 1;
8366a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8367a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
8368a8036d6466b63ead629795b60772f160cca77c4cglennrp
8369197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  if (mng_info->write_png_colortype < 7)
8370a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8371a8036d6466b63ead629795b60772f160cca77c4cglennrp  /* BUILD_PALETTE
8372a8036d6466b63ead629795b60772f160cca77c4cglennrp   *
8373a8036d6466b63ead629795b60772f160cca77c4cglennrp   * Normally we run this just once, but in the case of writing PNG8
8374e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
8375e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
83768ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
83778ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
83788ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
83798ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
8380c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
838182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
83828ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
838382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
8384d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
838582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
83868ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
8387d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
8388a8036d6466b63ead629795b60772f160cca77c4cglennrp    /*
8389d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
8390d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
8391d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8392d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
8393d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
8394d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
8395d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8396d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8397d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
83988a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     * If image->alpha_trait is MagickFalse, we ignore the alpha channel
8399d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8400d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8401d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8402d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8403d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8406d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
84083c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8410d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
84118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
841216ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8415d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
84168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
841716ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
841816ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8419d6bf1617e99df0272b231855a933a74e99b6578fglennrp
842016ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
842116ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8422fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8423fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8433d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84358a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             "      image->alpha_trait=%.20g",(double) image->alpha_trait);
843603812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
84383c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8439fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
84407ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
84417ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
84438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
844416ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
84452cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
84477ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8453d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
845416ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
84557ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
84562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8457d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
846716ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
84712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8473d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
847483c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
847616ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
847716ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
84787ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
84798d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
84808d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84818d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
84837ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8485fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8486fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8487fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
84882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8489d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
84927ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
849316ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
849597fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
849817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy           if (image->alpha_trait == UndefinedPixelTrait ||
849916ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
85008d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
85028d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8504d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
850516ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
850616ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8507d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8510d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8511d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
851216ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, opaque+i))
8513d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8514d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8515d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
851616ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8517d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8518d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
851916ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
852016ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8521d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85228d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85238d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
852416ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
85258d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
85278d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8528d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
853016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
853116ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
853216ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
853316ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
853416ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
853516ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
853616ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
853716ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
8538972d1c4895c4ee6da1b6745e1bb9cb71ee5d6d08cristy                         GetPixelGray(image,q);
8539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8540d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8541d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8542d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
854416ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, transparent+i))
8545d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8547d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8548d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8549d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8550d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
855216ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85548d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85558d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8556d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8558d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8561d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
856216ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85658d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8566d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8567d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
856816ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
856916ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
857016ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8571d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8572d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8573d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8574d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8576d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8577d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
857816ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8579d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8580d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
85818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
858216ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8583d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
85853c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
85864054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
85874054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8588d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8589d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8590d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8592c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8593c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8594c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8595c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8596c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8597c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8598c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8599c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8600d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8601d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8602ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8603ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8604ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8605ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8606d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8607d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
860803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
86098e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8610c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8611388a8c871db8f82488f34c4f41fc64a58b8cfbf7glennrp               number_opaque++;
8612c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8613c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8614c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8615c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8616c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8617c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
861803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8619a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8620a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8621a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8622d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8624d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
86253241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8626d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8627d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8628d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8629d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8630d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
86313241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8632d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8633d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8634d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8635d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86363241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
86378d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
86388d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
86398d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8640fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8641d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8642d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
86430fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         ping_have_non_bw=MagickFalse;
86440fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
864545d4c34ce93ff377b9671844ffa1153b821061f6glennrp         if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
86460fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
864796bc620815234aaec28b928df51d1754cbe390dcglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
864896bc620815234aaec28b928df51d1754cbe390dcglennrp              "incompatible colorspace");
86497fb2652ba366fc984d1dbb0c66560b91c57dab78cristy           ping_have_color=MagickTrue;
865098b95773e388844e22c6e4006bb88396b33cf6b4glennrp           ping_have_non_bw=MagickTrue;
86510fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
86520fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
8653d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8654d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8655d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8656d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8657d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
86586185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
865916ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8660d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
86616185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8662e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8663e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8664e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
866516ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
866616ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8667e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8668e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8669e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8670e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8671e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
867216ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8673e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8674e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8675e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8676e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8677e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8678d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8679d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8680d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
86816185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8682d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8683d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8684d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8685d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
86866185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
868716ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
868816ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8689d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8690d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8691e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8692d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
869316ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8694d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8695e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8696d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8697bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8698bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
86994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8700d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8701d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
870216ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8703d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8704bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8705d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8706d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8707d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8708d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8709d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8710d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8711d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8712d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8713d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8714d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8715d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
87163241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8717d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8718d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
87193241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8720d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8721d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8722d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8723d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8724d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8725d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8726c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8727c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8728bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8729d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8730d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8731d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8732d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8733d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8734d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8735d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8736d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8737d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8738d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8739d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8740d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8741d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8742d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8743d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8744d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8745d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8746d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8747d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8748d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8749d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8750d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
87513241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8752d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8753d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8754d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8755d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8756d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8757d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8758d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
87596185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8760d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8761d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8762d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8763d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
87642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8765d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8766d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8767d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8768d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8769d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8770d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
877116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8772d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
87733faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
87743faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8775d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8776d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8777d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8778d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8779d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8780d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8781d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8782d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8783d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8784bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8785d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8786d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8787d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8788d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8789fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8790fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8791d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8792d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
879316ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
87943c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
879516ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8796d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
87973c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8798d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8799d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8800d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
880103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
880217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                  if ((image->alpha_trait == UndefinedPixelTrait ||
880316ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
880416ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
880516ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
880616ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
88076185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
880816ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8809d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
88106185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
881103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
881216ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8813d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8814d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8815d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8816d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8817d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8818d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8819d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8820d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8821d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8822d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8823d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8824d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8825d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8826d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8827d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8828d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
882916ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
883083c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8831d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8832d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
883372988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8834d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8835d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8836d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8837d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8838d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8839d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8840d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
884116ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8842d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
88436185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
88446185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
88453c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8846d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8847d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8848d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8849d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8850d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
88513c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8852d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8853d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
88543c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8855d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8856d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8857d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8858d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
885903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8860d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8861d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8862d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
88636185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8864d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8865d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8866d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8867d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
88686185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8869d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8870d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8871d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8872a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8873d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8874d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8875d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8876a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8877d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8878d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8879d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8880d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8881d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8882d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8883d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
88846185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
888503812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
888603812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8887d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
88883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8889c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8890c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8891fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8892c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8893c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8894c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8895c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8896c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8897c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8898fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8899c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8900130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8901130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8902130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8903c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8904130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8905c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8906c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8907c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8908fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8909c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8910c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
891116ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8912fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
891316ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8914c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8915fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8916c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8917c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
891816ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
89198ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
892016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelInfoPixel(image,&image->background_color,r);
892116ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
89228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
89238ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
892416ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
892516ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8926c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8927bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8928c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8929c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8930fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8931c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8932c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8933c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
893416ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
893516ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
893616ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
8937c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8938c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8939c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8940c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8941c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8942e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8943e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8944e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8945c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8946d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8947d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8948d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8949d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8950d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8951d337164012450d70d62e71cf4a308a29004f7d57glennrp
8952d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8953d337164012450d70d62e71cf4a308a29004f7d57glennrp
895491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8955d337164012450d70d62e71cf4a308a29004f7d57glennrp
8956d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8957d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8958d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8959d337164012450d70d62e71cf4a308a29004f7d57glennrp
8960d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8961d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8962d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8963d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
896416ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8965d337164012450d70d62e71cf4a308a29004f7d57glennrp
896616ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8967d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
8968d337164012450d70d62e71cf4a308a29004f7d57glennrp
8969d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
8970d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
897116ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
897254cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
897316ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8974d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
8975bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8976d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8977d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
8978d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8979d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8980d337164012450d70d62e71cf4a308a29004f7d57glennrp
8981d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
8982d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
8983d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8984d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
8985d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8986d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
89878e58efdecda887b08ef730d68290a61081ef2566glennrp
8988d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
8989d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
899091d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
8991d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8992d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8993d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
8994d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
8995d337164012450d70d62e71cf4a308a29004f7d57glennrp
899682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
899782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
899882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
899982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
900082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
900182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
900282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
900382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
900491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
900582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
900682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
900782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9008e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
900982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
901082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
901182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
901282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
901382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
901416ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
901582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
901616ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
901782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
901882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
901982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
902082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
902116ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
902216ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
902316ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
902482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
9025bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
902682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
902782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
902882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
902982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
903082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
903182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
903282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
903382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
903482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
903582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9036e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
903782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
903882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
903991d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
904082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
9041d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9042d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
904382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
9044c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90458ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
9046c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
9047c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9048c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9049c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
9050c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90518ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
90528ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
90533faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
90543faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
90553faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
90563faa9a3fb01696daaf976d595f492cb530bffb21glennrp
905791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
9058fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9059c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9060c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9061e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
9062fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9063c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
9064c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9065c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
9066c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
906716ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
90688d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
906916ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
9070c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
9071c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
9072c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
9073c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
907416ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
907554cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
907616ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
9077c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
9078bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9079c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
9080c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
9081c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9082c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
9083c722dd852e8abe407c2846d39662f7ade9c234deglennrp
9084c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
9085c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
9086c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9087c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
9088c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9089e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
9090c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
9091c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
909291d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
9093c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9094c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
9095c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
9096c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
90978ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
90988ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
90998ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
910034ef720923a27004960cbcf4d75a8075445e85d7glennrp      /* Take care of special case with 256 opaque colors + 1 transparent
91018ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
91028ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
91038ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
91048ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
910534ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
910634ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
910734ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red background colors to 3-3-2-1");
910834ef720923a27004960cbcf4d75a8075445e85d7glennrp
91098ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
91108ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
91118ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
91128ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91138ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
91148ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
9115bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
911634ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
911734ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
911834ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red pixel colors to 3-3-2-1");
911934ef720923a27004960cbcf4d75a8075445e85d7glennrp
91208ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
91218ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
91238ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
912416ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
9125bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
912616ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
91278ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
9128bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91298ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
91308ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
913116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
913216ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
913316ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
913416ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
91358ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
913616ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
91378ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
913816ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
91398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
9140bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91418ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
91428ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
9143bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91448ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
91458ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91468ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91478ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
91488ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91498ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
91508ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
91518ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
91528ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
91538ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
91548ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
91558ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
91568ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
91578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
91588ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91598ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
9160fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
9161a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
9162fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
9163fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9164fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
9165fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
9166fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
9167fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
91680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
91690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
91700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
9171d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
91720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
91740e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
91750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
91770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
91780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91798d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
9180d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
91810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
91820b206f5daa453dc1035db5890cabc899736dc2d0glennrp
91830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
91840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
9185fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
9186fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
9187fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
91885a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
91895a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
91905a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
9191fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
91925a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
91935a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
9194fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
9195fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
9196fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9197fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
9198fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
9199fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9200fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
9201fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
9202fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
920316ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
9204fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
9205fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9206fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
9207fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
9208fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
9209fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
921016ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
9211fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
9212fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9213fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
9214fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
921516ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
921616ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
921716ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
921816ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
921916ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
922016ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
922116ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
9222fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
9223fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
9224fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
9225fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
9226fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
922716ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
9228fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
9229bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9230fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
9231fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
9232fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
9233fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9234fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
9235fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
923667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
923767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
923867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
9239fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
924067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
924167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
924267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
924367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
9244fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
924567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
924667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
9247fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
9248fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9249bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9250fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
9251fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
9252fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
9253fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9254fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
9255fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9256fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
9257fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9258fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
9259fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9260fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
9261fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
9262fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
9263fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
92643c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
92653c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
92663c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
92673c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
9268f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
926917f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  image_matte=image->alpha_trait != UndefinedPixelTrait ? MagickTrue : MagickFalse;
927083c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
927148c20621d4ce02a3833b107f710843d1e524d559glennrp  if (mng_info->write_png_colortype < 5)
9272197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette=image->storage_class == PseudoClass &&
9273197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      image_colors <= 256 && image->colormap != NULL;
9274197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  else
9275197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette = MagickFalse;
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
927752a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
927852a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
927952a479ca718756af72f96e127f8256499ab68f76glennrp    {
928016ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
928116ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
928216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
928315e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
928416ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
928552a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
928652a479ca718756af72f96e127f8256499ab68f76glennrp    }
928752a479ca718756af72f96e127f8256499ab68f76glennrp
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
92903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
929216ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
929316ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
92943e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
9295cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
9296cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
92970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
92993e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
9300cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
93010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
93070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
93150997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=(MemoryInfo *) NULL;
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
9327868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9328cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9330edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
93310997332e2c35a821b271d6e7473c01c10dc206adcristy      if (pixel_info != (MemoryInfo *) NULL)
93320997332e2c35a821b271d6e7473c01c10dc206adcristy        pixel_info=RelinquishVirtualMemory(pixel_info);
9333edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9334edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (quantum_info != (QuantumInfo *) NULL)
9335edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        quantum_info=DestroyQuantumInfo(quantum_info);
9336edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
933716ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
933816ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
933916ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
934016ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9343edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9344edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
9345edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
9346edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
9347edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
9348edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9349868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9350edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
9351edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
9352edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9353943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
9354a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
9355a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
9356a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
9357a3a5f956194e91458e2789966ad15308e8f3df47glennrp
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93619bf97b6c2143eb20c330346b01e82102cc082725glennrp
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
936425024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  {
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
936625024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
936725024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     /* Disable new libpng-1.5.10 feature when writing a MNG because
936825024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      * zero-length PLTE is OK
936925024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      */
937025024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     png_set_check_for_invalid_index (ping, 0);
937125024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# endif
937225024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  }
93732b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
93782b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93812b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
93832b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93844e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
93854e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
93862b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
93890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9390fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48 || mng_info->write_png64)
9391fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     image_depth=16;
9392fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
93950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
93990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
94050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9409e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9411e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94138a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        "    image_matte=%.20g",(double) image->alpha_trait);
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94158640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94178640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94198640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
94215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
9422dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
942326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
942526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
942626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
942716ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
9431dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9432dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9436dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
9437823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
943816ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
9439823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
944016ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9442dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9445dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
944616ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
944716ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9449991d11dd9c33e65872778b81aff1347cd2878154glennrp
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9452dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
945316ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
945416ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9456991d11dd9c33e65872778b81aff1347cd2878154glennrp
9457823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9458823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9459823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9460823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9461823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9462991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
946426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9466a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
946726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
946826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9469a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9471a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9472a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9473a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9474a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9475a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9476a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
94770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9478a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9479a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
94800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9481a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9482a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
94830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9484a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9485a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
94860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9487a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9488a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
94890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9490a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9491a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
94920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9493a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9494a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9495c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9496c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
94970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
94980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
95003b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
95013b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95023b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9503c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9504c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9505c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
95063b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
95073b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
95093b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
95100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
951226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
95153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
95173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
95183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
95190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95201273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
95213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9522fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
95230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
95240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
95268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
95278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
95280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
95300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
95310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
95320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
95330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
95350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9537f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
95380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
95400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
95410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
95420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
95430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
95440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
95450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
954667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
95470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
954867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
954967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
955067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
95510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
95542b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
95568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
95578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
95585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
955958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
95608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
95610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
95620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
95630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
95640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
95658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
95688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
95690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95712cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
95728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
95730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
95750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
95760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
95788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
95798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
95800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95811273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
95824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
95831273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
95841273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
95851273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
95861273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
95874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
95884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
95894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
95900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9592c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9593c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9594c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9595c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9596c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9597c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9598c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
95994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
96010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9602fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png_colortype == 1)
9603fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
9604fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image_matte=MagickFalse;
9605fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
9606fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
9607fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
9608fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png24 || mng_info->write_png48 ||
9609fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 3)
96103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
96125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9615fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png32 || mng_info->write_png64 ||
9616fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 7)
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
96195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
96250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
96273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
96290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
96315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
96332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
96367c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
96377c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
96387c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96397c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96427c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
96433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96463c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
96470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9648d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
96498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
96500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9651d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9657d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
96613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96635aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
96645aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
96655aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
96665aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
96677c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
9668261f64eea2c3a5a9586da65af2c59d2a39b05de0glennrp             image_info->type == UndefinedType)
96693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96705aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
96718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
96725aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
96735aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
96755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
96765aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96780b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
96795aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96805aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
96815aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
96825aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
96845aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
96855aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
96865aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
96875aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96885aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96895aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
96905aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
96920b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
96935aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96945aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
96955aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
96965aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96975aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
96980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
96995aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
970326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97048640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
970526c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
97065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
97070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
97080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
97090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
97100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
97110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
97120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
97133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9714d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9715d6bf1617e99df0272b231855a933a74e99b6578fglennrp
97165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
97173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
971817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy          if (image->alpha_trait == UndefinedPixelTrait && ping_have_non_bw == MagickFalse)
97198d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
97203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97218640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
97233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
972435ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
97255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
97260f111984738842d27d04aed2a3f823d82a943506glennrp
97270f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
97280f111984738842d27d04aed2a3f823d82a943506glennrp           {
97290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9730edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"image has 0 colors");
97310f111984738842d27d04aed2a3f823d82a943506glennrp           }
97320f111984738842d27d04aed2a3f823d82a943506glennrp
973335ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
97345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9735d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
97363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9737d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9738d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9739d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9740d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
97410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9742d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9743d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9744d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
97450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9746d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9747d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
97483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
97512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97551a56e9c9268976936eeab9fe97eb664b847e444cglennrp        "    Tentative PNG color type: %s (%.20g)",
97561a56e9c9268976936eeab9fe97eb664b847e444cglennrp        PngColorTypeToString(ping_color_type),
97571a56e9c9268976936eeab9fe97eb664b847e444cglennrp        (double) ping_color_type);
97580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9760e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
97610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9763e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
97640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97663c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
97678640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
97688640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97698640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9770e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
977358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
97743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
97764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
97777c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
97787c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
97797c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
97802b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97817c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
97827c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
97837c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
97842b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
97864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
97873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
97884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
97894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
97904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
97914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
97924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9793a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
97944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
97957c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
97967c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
97977c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
97984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
97990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
98014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9803bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
98043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
98060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
98084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
98090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
98114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
98120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
98144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
98150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
98174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
98180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
98204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
98210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
98234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
98240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
98264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
98270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
982916ea139d53d867211d3bb0fa859a83de653f687ecristy                (ScaleQuantumToShort(GetPixelInfoIntensity(
98304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
98310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
98330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
98354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9840fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9841fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9842fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9843fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9844fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
98454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98497c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98507c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
98510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
98534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
98544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
98554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
98564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
98574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
98584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
98594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
98614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
98624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
98655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
98665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
98675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
98685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98728640fb5e9b1094f35f8beab436f81661b8a99448glennrp
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
98740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98752e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
98763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
98770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
987839992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
98793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
98808d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
98818d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
988335ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
98840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
98869c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
98870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98887c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
98905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
98914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
98934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
98944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
98954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
98964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
98984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
98994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
99004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
99050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9906136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9907d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9908f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
99090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
99115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
99120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
99165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
99205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
99210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
992235ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9923bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
99245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99272b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
99290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
99331a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
99343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
99353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
99373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9939bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
99403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
99504bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
99513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
99532b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
99559c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
99560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
99589c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
99590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
99619c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
99670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
99690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
997217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
997317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
99795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
99800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99813d627862fb79aad8a20be4f1587f0b8761db441aglennrp            if (!(mng_info->have_write_global_plte && matte == MagickFalse))
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9983bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
99853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
99890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99903b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
99913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
999298156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
9993f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
99940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
999539992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
99963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
9999d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10001befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
10002befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
10003befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
100045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
10005befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
100060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1000716ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
100085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
100120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1001358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
100140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
100150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
10016d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
10017d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
100180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10020d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
10021d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
100240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
100250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10026d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
100270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
10028c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
10029c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
10030c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10031c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
10032c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
10033d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
10034d6bf1617e99df0272b231855a933a74e99b6578fglennrp
10035d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
10036d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
10037750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp                       ping_trans_alpha[i]= (png_byte)
1003816ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
10039d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
100400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
100410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
100423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10047c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
100483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
100493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
100500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
100523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
100534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
100574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
100635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
100645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
100655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
100664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
100714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100784383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
100794383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
100802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
100823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
100833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
100845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
100853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
100863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
100873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
100883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1009035ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
1009135ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
1009235ef824baa82511126ff0072ae30eee0da9c05a3cristy
1009322ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
100943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
1009626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1009816ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
1009916ea139d53d867211d3bb0fa859a83de653f687ecristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(
1010016ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
1010116ea139d53d867211d3bb0fa859a83de653f687ecristy
101023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
101038f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1010416ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
1010516ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1010616ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
1010716ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
101083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
10109991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
1011026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
101113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101123e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101133e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101143e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
101153e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
101163e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101179be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
101183e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
101193e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101203e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101213e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101223e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1012417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1012526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1012626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
101271273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
1012817a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
1012917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
1013017a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
1013117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
1013217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1013317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
1013417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10135a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
10136a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
1013717a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
1013817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1013917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
1014017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101413b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
101420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
101430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
101450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
10146a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1014713d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
10148a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
101490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
101503b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
101513b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
101530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
101550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
101560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
101570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
101580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
10159a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
1016017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10161d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
101623c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
101633b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101643b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101653b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
101663c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
101673c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
1016817a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
1016926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1017017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101731a56e9c9268976936eeab9fe97eb664b847e444cglennrp      "    PNG color type: %s (%d)", PngColorTypeToString(ping_color_type),
101741a56e9c9268976936eeab9fe97eb664b847e444cglennrp      ping_color_type);
101753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
101763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
101800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
101820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
101850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
101860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
101880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
101920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101934054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
101944054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
1019510d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
1019610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1019710d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
1019810d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
1019910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1020010d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
1020110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10202ef804f5802b3d6517d516556b64fccc5843710b6glennrp        0 or omitted: Use Z_HUFFMAN_ONLY strategy with the
1020310d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
1020410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1020510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
1020610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1020710d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
1020810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1020910d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
1021010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1021110d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
1021210d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
1021310d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
10214750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
1021510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
1021610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1021710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
1021885dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             a MNG, otherwise "none".  Did not work in IM-6.7.0-9
1021910d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
1022010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022185dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp        8:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), adaptive
1022285dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             filtering. Unused prior to IM-6.7.0-10, was same as 6
1022310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10224ef804f5802b3d6517d516556b64fccc5843710b6glennrp        9:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), no PNG filters
102251868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
1022610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022710d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
1022810d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
1022916ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
1023016ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
1023110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1023210d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
1023310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1023429dd80efe8d7489d5f689a8a723454e684f92a8fdirk  quality=image_info->quality == UndefinedCompressionQuality ? 75UL :
1023529dd80efe8d7489d5f689a8a723454e684f92a8fdirk     image_info->quality;
102360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102371868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
102381868258559ddf946fa73ef72dd43507b32623705glennrp    {
102391868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
102401868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
102411868258559ddf946fa73ef72dd43507b32623705glennrp    }
10242750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
102431868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
102443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
102463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
102473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10248bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
102490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102501868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
102511868258559ddf946fa73ef72dd43507b32623705glennrp    }
102520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102531868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
102541868258559ddf946fa73ef72dd43507b32623705glennrp    {
102551868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
10256a24b245fac14ef0617d691de0942697f2eb31b05glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
10257a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy=Z_RLE+1;
10258a24b245fac14ef0617d691de0942697f2eb31b05glennrp#else
10259a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
10260a24b245fac14ef0617d691de0942697f2eb31b05glennrp#endif
102613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102631868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
102641868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
102651868258559ddf946fa73ef72dd43507b32623705glennrp
102661868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
102673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102681868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
102693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102701868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
102711868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
102720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102731868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
102741868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102751868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
102761868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
102770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102781868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102791868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
102803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102814054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
1028210d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102831868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
102844054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
102854054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
102861868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102871868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
102881868258559ddf946fa73ef72dd43507b32623705glennrp        else
102891868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102901868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
102911868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
102923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102941868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
102951868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
102960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102971868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
102981868258559ddf946fa73ef72dd43507b32623705glennrp    {
102991868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
103001868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
103011868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
103021868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103031868258559ddf946fa73ef72dd43507b32623705glennrp      else
103041868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
103051868258559ddf946fa73ef72dd43507b32623705glennrp     }
103064054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
103071868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
103081868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
1030910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
103101868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
103111868258559ddf946fa73ef72dd43507b32623705glennrp    {
103121868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
103131868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
103141868258559ddf946fa73ef72dd43507b32623705glennrp      {
103151868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
103161868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
103171868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
103181868258559ddf946fa73ef72dd43507b32623705glennrp      }
103191868258559ddf946fa73ef72dd43507b32623705glennrp#endif
103204054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103211868258559ddf946fa73ef72dd43507b32623705glennrp    }
103220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103231868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
103241868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103261868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
103271868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
103281868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
103290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103301868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
103311868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
103321868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
103332b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10334dec72c9b492c176af9813be3105518e91835ed37glennrp  ping_interlace_method=image_info->interlace != NoInterlace;
10335dec72c9b492c176af9813be3105518e91835ed37glennrp
10336dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_mng)
10337dec72c9b492c176af9813be3105518e91835ed37glennrp    png_set_sig_bytes(ping,8);
10338dec72c9b492c176af9813be3105518e91835ed37glennrp
10339dec72c9b492c176af9813be3105518e91835ed37glennrp  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
10340dec72c9b492c176af9813be3105518e91835ed37glennrp
10341dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_png_colortype != 0)
10342dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10343dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
10344dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10345dec72c9b492c176af9813be3105518e91835ed37glennrp         {
10346dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
10347dec72c9b492c176af9813be3105518e91835ed37glennrp
10348dec72c9b492c176af9813be3105518e91835ed37glennrp           if (ping_bit_depth < 8)
10349dec72c9b492c176af9813be3105518e91835ed37glennrp             ping_bit_depth=8;
10350dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10351dec72c9b492c176af9813be3105518e91835ed37glennrp
10352dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
10353dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10354dec72c9b492c176af9813be3105518e91835ed37glennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
10355dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10356dec72c9b492c176af9813be3105518e91835ed37glennrp
10357dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_need_colortype_warning != MagickFalse ||
10358dec72c9b492c176af9813be3105518e91835ed37glennrp     ((mng_info->write_png_depth &&
10359dec72c9b492c176af9813be3105518e91835ed37glennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
10360dec72c9b492c176af9813be3105518e91835ed37glennrp     (mng_info->write_png_colortype &&
10361dec72c9b492c176af9813be3105518e91835ed37glennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10362dec72c9b492c176af9813be3105518e91835ed37glennrp      mng_info->write_png_colortype != 7 &&
10363dec72c9b492c176af9813be3105518e91835ed37glennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
10364dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10365dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10366dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10367dec72c9b492c176af9813be3105518e91835ed37glennrp          if (ping_need_colortype_warning != MagickFalse)
10368dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10369dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10370dec72c9b492c176af9813be3105518e91835ed37glennrp                 "  Image has transparency but tRNS chunk was excluded");
10371dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10372dec72c9b492c176af9813be3105518e91835ed37glennrp
10373dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_depth)
10374dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10375dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10376dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:bit-depth=%u, Computed depth=%u",
10377dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_depth,
10378dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_bit_depth);
10379dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10380dec72c9b492c176af9813be3105518e91835ed37glennrp
10381dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_colortype)
10382dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10383dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10384dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:color-type=%u, Computed color type=%u",
10385dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_colortype-1,
10386dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_color_type);
10387dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10388dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10389dec72c9b492c176af9813be3105518e91835ed37glennrp
10390dec72c9b492c176af9813be3105518e91835ed37glennrp      png_warning(ping,
10391dec72c9b492c176af9813be3105518e91835ed37glennrp        "Cannot write image with defined png:bit-depth or png:color-type.");
10392dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10393dec72c9b492c176af9813be3105518e91835ed37glennrp
1039417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  if (image_matte != MagickFalse && image->alpha_trait == UndefinedPixelTrait)
10395dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10396dec72c9b492c176af9813be3105518e91835ed37glennrp      /* Add an opaque matte channel */
10397dec72c9b492c176af9813be3105518e91835ed37glennrp      image->alpha_trait = BlendPixelTrait;
10398dec72c9b492c176af9813be3105518e91835ed37glennrp      (void) SetImageAlpha(image,OpaqueAlpha,exception);
10399dec72c9b492c176af9813be3105518e91835ed37glennrp
10400dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10401dec72c9b492c176af9813be3105518e91835ed37glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10402dec72c9b492c176af9813be3105518e91835ed37glennrp          "  Added an opaque matte channel");
10403dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10404dec72c9b492c176af9813be3105518e91835ed37glennrp
10405dec72c9b492c176af9813be3105518e91835ed37glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10406dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10407dec72c9b492c176af9813be3105518e91835ed37glennrp      if (ping_color_type < 4)
10408dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10409dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_have_tRNS=MagickTrue;
10410dec72c9b492c176af9813be3105518e91835ed37glennrp           if (logging != MagickFalse)
10411dec72c9b492c176af9813be3105518e91835ed37glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10412dec72c9b492c176af9813be3105518e91835ed37glennrp               "  Setting ping_have_tRNS=MagickTrue.");
10413dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10414dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10415dec72c9b492c176af9813be3105518e91835ed37glennrp
10416dec72c9b492c176af9813be3105518e91835ed37glennrp  if (logging != MagickFalse)
10417dec72c9b492c176af9813be3105518e91835ed37glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10418dec72c9b492c176af9813be3105518e91835ed37glennrp      "  Writing PNG header chunks");
10419dec72c9b492c176af9813be3105518e91835ed37glennrp
10420dec72c9b492c176af9813be3105518e91835ed37glennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
10421dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_bit_depth,ping_color_type,
10422dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_interlace_method,ping_compression_method,
10423dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_filter_method);
10424dec72c9b492c176af9813be3105518e91835ed37glennrp
10425dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
10426dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10427dec72c9b492c176af9813be3105518e91835ed37glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
10428dec72c9b492c176af9813be3105518e91835ed37glennrp
10429dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10430dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10431dec72c9b492c176af9813be3105518e91835ed37glennrp          for (i=0; i< (ssize_t) number_colors; i++)
10432dec72c9b492c176af9813be3105518e91835ed37glennrp          {
10433dec72c9b492c176af9813be3105518e91835ed37glennrp            if (i < ping_num_trans)
10434dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10435dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10436dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10437dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10438dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10439dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue,
10440dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10441dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) ping_trans_alpha[i]);
10442dec72c9b492c176af9813be3105518e91835ed37glennrp             else
10443dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10444dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d)",
10445dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10446dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10447dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10448dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue);
10449dec72c9b492c176af9813be3105518e91835ed37glennrp           }
10450dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10451dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10452dec72c9b492c176af9813be3105518e91835ed37glennrp
104530d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
104540d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
104553d627862fb79aad8a20be4f1587f0b8761db441aglennrp     (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
104560d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
104570d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
104580d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
104590d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
10460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
10461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
10462c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
104633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10464c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
104650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10466c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
10467c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
10468c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
10469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
10470c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
1047126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
10472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
10473c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
10474c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
10475ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10476ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          "  Setting up iCCP chunk");
10477ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
1047816ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
10479e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
10480c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
10481e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
10482e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
10483e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
10484c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
10485918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                       ping_have_iCCP = MagickTrue;
10486c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
1048726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
104880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10489c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
104903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10491c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
10492c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
10493ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10494ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      "  Setting up zTXT chunk with uuencoded ICC");
10495cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
10496c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
10497c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
10498c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
10499ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  ping_have_iCCP = MagickTrue;
10500c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
10501c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
105020b206f5daa453dc1035db5890cabc899736dc2d0glennrp
10503c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
10504c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10505c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
105060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10507c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
10508c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
105090d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
105103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
105113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
105133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
10514ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_have_iCCP != MagickTrue &&
10515ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      (ping_have_sRGB != MagickFalse ||
10516ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1051826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
1051926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1052026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
1052126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
1052226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
1052326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
1052426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
105260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1052726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
10528cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
10529cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
10530918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp
10531918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB = MagickTrue;
1053226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
105333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1053426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
105355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105382cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
10539918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_iCCP == MagickFalse &&
10540918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB == MagickFalse &&
105412cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
1054226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
1054326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
105443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
105473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
105493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
105503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
105513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
105533b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
105543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
105553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1055626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
105572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10558918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp      if (ping_exclude_cHRM == MagickFalse && ping_have_sRGB == MagickFalse)
105593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1056026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
1056126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
1056226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
1056326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
1056426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
10565918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                Note: if cHRM+gAMA == sRGB write sRGB instead.
1056626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
1056726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
1056826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
1056926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
1057026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
1057126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
1057226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1057326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1057426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1057526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1057626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1057726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1057826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1057926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1058026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1058126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1058226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1058326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1058426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1058526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10587dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1058826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1058926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1059026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10591c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1059226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
105938fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10594c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10595c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10596c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10597c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10598c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10599c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10600c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10601c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10602c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10603c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10604c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10605c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10606c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10607c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1060826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10609991d11dd9c33e65872778b81aff1347cd2878154glennrp
1061026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10611dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1061226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1061326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1061426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1061526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1061626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1061726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10618823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
106198fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10620823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10621823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10622823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10623823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10624823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10625823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10626823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10627823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10628823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10629823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10630823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10631823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10632823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1063326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10634dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10635dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10636dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
106374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10638dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1063926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1064026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1064126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1064226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10643dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1064426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1064526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1064626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1064726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1064826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10649dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10650dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10651dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10652fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
10653fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (ping_exclude_tIME == MagickFalse)
10654fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
10655fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      const char
10656fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        *timestamp;
10657fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
1065839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      if (image->taint == MagickFalse)
10659fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
1066039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          timestamp=GetImageOption(image_info,"png:tIME");
1066139d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1066239d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          if (timestamp == (const char *) NULL)
10663fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            timestamp=GetImageProperty(image,"png:tIME",exception);
10664fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
1066539d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1066639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      else
1066739d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp        {
1066839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1066939d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp             "  Reset tIME in tainted image");
1067039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1067139d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          timestamp=GetImageProperty(image,"date:modify",exception);
1067239d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp        }
1067339d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1067439d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      if (timestamp != (const char *) NULL)
1067539d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          write_tIME_chunk(image,ping,ping_info,timestamp,exception);
10676fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
10677fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
1067839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
10679da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10680da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1068116ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10682da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10683da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10684da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10685da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10686da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10687da8f3a7bfddac2680a3069a490db541e7944edafglennrp
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10689991d11dd9c33e65872778b81aff1347cd2878154glennrp
1069039992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10691991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
106923b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
106930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
106940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
106960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10697991d11dd9c33e65872778b81aff1347cd2878154glennrp
106980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
106990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
107000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
107010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
107020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10703991d11dd9c33e65872778b81aff1347cd2878154glennrp
107040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
107050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
107070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
107080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
107090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
107100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107113b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
107120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
107130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10714c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
107150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
107160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
107170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
107180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
107190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
107200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10721991d11dd9c33e65872778b81aff1347cd2878154glennrp
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10723cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10724da8f3a7bfddac2680a3069a490db541e7944edafglennrp
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10726991d11dd9c33e65872778b81aff1347cd2878154glennrp
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10728cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1073026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
107334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1073426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1073526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1073626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1073726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1073826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1073926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1074003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1074126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1074226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1074326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1074426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1074526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1074626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
107509c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
107529c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10761b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10762b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
107637202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10765b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10767b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10769b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10770b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10771b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10773b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10775b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10777b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10778b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
107813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10783b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10784b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
107850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10786b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10787e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107890997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=AcquireVirtualMemory(rowbytes,sizeof(*ping_pixels));
107900997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
10791edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Allocation of memory for pixels failed");
107920997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
107930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107975f766ef8b0cd9906c2c3a56d845828380a251073cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10798ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10799edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation for quantum_info failed");
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
108024b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
108048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10806fd164d2bf84b111e304959af5698757d60e9b8aeglennrp       !mng_info->write_png48 && !mng_info->write_png64 &&
108078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
108088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
108108d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
108118d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1081416ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
108160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10823bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10825d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
108263b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108273b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10828a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1082916ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
108300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1083116ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
108323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
108330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1083616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1083716ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10843bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10844cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1085116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1085216ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10856bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10857cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
108590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108603b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10861b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10862b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
108630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10864cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
10865af9320404a7b05014476f844b11110157a21b73eglennrp
10866af9320404a7b05014476f844b11110157a21b73eglennrp          status=SetImageProgress(image,LoadImageTag,
10867af9320404a7b05014476f844b11110157a21b73eglennrp              (MagickOffsetType) (pass * image->rows + y),
10868af9320404a7b05014476f844b11110157a21b73eglennrp              num_passes * image->rows);
10869af9320404a7b05014476f844b11110157a21b73eglennrp          if (status == MagickFalse)
10870af9320404a7b05014476f844b11110157a21b73eglennrp            break;
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10878fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png48 && !mng_info->write_png64 &&
10879fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png32) && (image_matte != MagickFalse ||
10880fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
10881fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (mng_info->IsPalette) && ping_have_color == MagickFalse)
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1088316ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
108848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
108850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
108888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10889bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1089116ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
108922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1089316ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
108952cc891a179d622dde7bbb8854138851e828bc6eaglennrp
108965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
108973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
108988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1089916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1090016ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
109012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1090316ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1090416ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
109052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
109078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10912b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
109133b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10914b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
109162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1091716ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1091816ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
10919b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
109202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109213b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10922b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
109242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10925cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
109262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10927af9320404a7b05014476f844b11110157a21b73eglennrp            status=SetImageProgress(image,LoadImageTag,
10928af9320404a7b05014476f844b11110157a21b73eglennrp              (MagickOffsetType) (pass * image->rows + y),
10929af9320404a7b05014476f844b11110157a21b73eglennrp              num_passes * image->rows);
10930af9320404a7b05014476f844b11110157a21b73eglennrp            if (status == MagickFalse)
10931af9320404a7b05014476f844b11110157a21b73eglennrp              break;
109328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
109338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
109348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
109350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1093816ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
109398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
109400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10943fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            if ((image_depth > 8) ||
10944fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 ||
109458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
10946fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 ||
10947fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png64 ||
10948fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
109498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
109508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10951b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
10952862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
109532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1095416ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
109558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
109562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
109598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1096016ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1096116ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
109622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1096416ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1096516ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
109668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
109698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1097016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10971cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1097216ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
109732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
109758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
109778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1098016ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1098116ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
109822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1098416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1098516ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
109862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109873b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10988b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
109902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10991cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
10992af9320404a7b05014476f844b11110157a21b73eglennrp
10993af9320404a7b05014476f844b11110157a21b73eglennrp                status=SetImageProgress(image,LoadImageTag,
10994af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) (pass * image->rows + y),
10995af9320404a7b05014476f844b11110157a21b73eglennrp                  num_passes * image->rows);
10996af9320404a7b05014476f844b11110157a21b73eglennrp                if (status == MagickFalse)
10997af9320404a7b05014476f844b11110157a21b73eglennrp                  break;
10998b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
109998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
110002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
11002fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            /* not ((image_depth > 8) ||
11003fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 || mng_info->write_png32 ||
11004fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 || mng_info->write_png64 ||
11005fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
11006fd164d2bf84b111e304959af5698757d60e9b8aeglennrp             */
110078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
110088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
110098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
110108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
110118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
110128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
110142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
110168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
110178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
110182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
110208640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
110218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
110228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
110242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1102516ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
110262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1102716ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
110288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1103144757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
110324bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
110334bf89731a90c6e03598950223e19e7be7b95d630glennrp
1103416ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1103516ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1103644757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
110372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
110398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
110408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
110418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
110432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1104416ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
11045cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1104616ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
110478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
110482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
110508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1105116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1105216ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
110532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110545eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
110555eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
110565eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110571a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
110585eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
110595eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110605eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
110615eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
110625eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
110638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
11064cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
110652cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11066af9320404a7b05014476f844b11110157a21b73eglennrp                status=SetImageProgress(image,LoadImageTag,
11067af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) (pass * image->rows + y),
11068af9320404a7b05014476f844b11110157a21b73eglennrp                  num_passes * image->rows);
110698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
110708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110718640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
11072af9320404a7b05014476f844b11110157a21b73eglennrp            }
110733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
110768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
11077b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
11078b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11083b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
110840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11086e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
110870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11089e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
110900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110945d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
110990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111035d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
111080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11113a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11115823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1111726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1111826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1111926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1112026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1112126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1112226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
111232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1112416ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
11125a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11126e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      /* Don't write any "png:" or "jpeg:" properties; those are just for
11127e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       * "identify" or for passing through to another JPEG
11128e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       */
11129e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      if ((LocaleNCompare(property,"png:",4) != 0 &&
11130a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp           LocaleNCompare(property,"jpeg:",5) != 0) &&
11131e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp
11132a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11133a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
11134a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
11135823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
11136a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
11137a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11138a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
11139a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
11140a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1114126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
11142c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
11143c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
11144a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy
11145ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
11146a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,
11147a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy                 (png_alloc_size_t) sizeof(png_text));
11148a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
11149a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
11150a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
11151c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
11152c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
11153c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
111542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11155c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
11156c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
111572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11158c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
11159c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
111602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11161c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1116226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
11163c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
11164c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
11165c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
11166c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1116726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
111682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11169c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
11170c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
11171c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11172c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
11173c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11174c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11175cbc9215c23fce410bf0bea825dee908c15271bb3glennrp                  "    keyword: '%s'",text[0].key);
11176c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
11177c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11178c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
11179c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
11180c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1118126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1118226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1118326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
111843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
111853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
11187cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
111883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
111920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
111940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
111985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
111995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1120903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
112205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
112235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
112290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
11235edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
112360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112430997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1124516ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1124616ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1124716ea139d53d867211d3bb0fa859a83de653f687ecristy
1124816ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1124916ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1125016ea139d53d867211d3bb0fa859a83de653f687ecristy
11251b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
11252b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
11253b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
11254b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1125516ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
11256b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
112600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11261868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
11262edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
11263edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
11264edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
11265edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   /* }  for navigation to beginning of SETJMP-protected block. Revert to
11266edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    *    Throwing an Exception when an error occurs.
11267edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    */
11268edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
112703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
11271edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
112803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
112873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
112893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1129216ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1129316ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1130116ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1130216ea139d53d867211d3bb0fa859a83de653f687ecristy%
113033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
113095d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
113125a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
113133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
113155a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
113165a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
11317e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
11318130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
11319130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
11320130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
11321e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
11322e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
11323e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
113245a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
113255a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
113275a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
113285a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
113295a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
113303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
113323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
113335a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
113345a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
113355a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
113365a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
113375a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
113383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
113403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
113413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
113420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
113435a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
113445a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
113453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11346fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG48:   A 16-bit per sample RGB PNG datastream is written.  The tRNS
11347fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               chunk can be present to convey binary transparency by naming
11348fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               one of the colors as transparent.  If the image has more
11349fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               than one transparent color, has semitransparent pixels, or
11350fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               has an opaque pixel with the same RGB components as the
11351fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparent color, an image is not written.
11352fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
11353fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG64:   A 16-bit per sample RGBA PNG is written.  Partial
11354fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparency is permitted, i.e., the alpha sample for
11355fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               each pixel can have any value from 0 to 65535. The alpha
11356fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               channel is present even if the image is fully opaque.
11357fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
113585830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%    o PNG00:   A PNG that inherits its colortype and bit-depth from the input
113595830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               image, if the input was a PNG, is written.  If these values
113605830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               cannot be found, then "PNG00" falls back to the regular "PNG"
113615830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               format.
113625830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
113643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
113653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
11366bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
11367bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
11368bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
113693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
113713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
113733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
113743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
113763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
113773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
113793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
113803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
113843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
113853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11386fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               If the image cannot be written without loss with the
11387fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               requested bit-depth and color-type, a PNG file will not
11388fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               be written, a warning will be issued, and the encoder will
11389fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               return MagickFalse.
113905a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
113945a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1139516ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
114033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
114043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
114053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
114073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
114093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
11410bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
11411bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
114123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
11416bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
114173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11418bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114203241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
114210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
11422d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
114230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
114240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
114250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
11426cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
114270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
11428d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
11429d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
114305d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
11431d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
11432d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
11433d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
11434d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
114350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
114363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
114383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1143916ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
114403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
114413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1144221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1144321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1144421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
114453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
114463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
114483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
114493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
114513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
114523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
114545c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
114555c7cf4e469a4dad7e277783749155932252c52dfglennrp
114563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
114603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
114613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11464fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1146973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
114700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
114723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
114730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
11479a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
114813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
11487fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png48=LocaleCompare(image_info->magick,"PNG48") == 0;
11488fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png64=LocaleCompare(image_info->magick,"PNG64") == 0;
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11490092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:format");
114915a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp  if (value == (char *) NULL)
114925a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp    if (LocaleCompare(image_info->magick,"PNG00") == 0)
11493b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
114945a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp  if (value != (char *) NULL || LocaleCompare(image_info->magick,"PNG00") == 0)
11495b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
11496f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11497f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp         "  Format=%s",value);
11498f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11499fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png8 = MagickFalse;
11500fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png24 = MagickFalse;
11501fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png32 = MagickFalse;
11502fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png48 = MagickFalse;
11503fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png64 = MagickFalse;
11504fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11505b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
11506b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
11507b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11508b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11509b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11510b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11511b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11512b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11513fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11514fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png48") == 0)
11515fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png48 = MagickTrue;
11516fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11517fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png64") == 0)
11518fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png64 = MagickTrue;
115195830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115205a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp      else if ((LocaleCompare(value,"png00") == 0) ||
115215a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp         LocaleCompare(image_info->magick,"PNG00") == 0)
115225830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        {
115233398b5b62521b49754d9391aae9e4511857bd63bglennrp          /* Retrieve png:IHDR.bit-depth-orig and png:IHDR.color-type-orig. */
115243398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.bit-depth-orig",exception);
11525f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11526f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11527f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11528f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11529f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited bit depth=%s",value);
11530f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11531f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"1") == 0)
11532f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 1;
11533f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115345a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"2") == 0)
11535f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 2;
11536f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115375a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"4") == 0)
11538f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 4;
11539f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11540f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"8") == 0)
11541f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 8;
11542f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11543f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"16") == 0)
11544f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 16;
11545f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
11546f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115473398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.color-type-orig",exception);
11548f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11549f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11550f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11551f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11552f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited color type=%s",value);
11553f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11554f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"0") == 0)
11555f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 1;
11556f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11557f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"2") == 0)
11558f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 3;
11559f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11560f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"3") == 0)
11561f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 4;
11562f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11563f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"4") == 0)
11564f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 5;
11565f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11566f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"6") == 0)
11567f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 7;
11568f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
115695830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        }
115705830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
115715830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
115733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115749c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
115759c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115769c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
115803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115819c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
115829c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115839c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1158517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      if (image->alpha_trait != UndefinedPixelTrait)
1158616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
115870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115889c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1158916ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
115900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1159116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
115923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115969c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
115979c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115989c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
1159947da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
116000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11601197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      (void) SetImageType(image,TrueColorMatteType,exception);
1160216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11605fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48)
11606fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11607fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 2 */ 3;
11608fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11609fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
11610fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
1161117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      if (image->alpha_trait != UndefinedPixelTrait)
116124dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
11613fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11614fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else
116154dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorType,exception);
11616fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
116174dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11618fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11619fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11620fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png64)
11621fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11622fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 6 */  7;
11623fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11624fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
1162547da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
11626fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11627197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      (void) SetImageType(image,TrueColorMatteType,exception);
116284dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11629fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11630fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11631092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:bit-depth");
116328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
116333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
116369c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
116370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116399c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
116400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
116429c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
116430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
116459c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
116460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
116489c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
116490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11650bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1165116ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11652bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11653bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11654bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11655bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
116579c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11658bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
116593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11661092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:color-type");
116620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
116663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
116679c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
116680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1166916ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1167016ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1167116ea139d53d867211d3bb0fa859a83de653f687ecristy
116723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116739c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
116740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
116769c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
116770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
116799c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
116800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
116829c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
116830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11684bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1168516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11686bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11687bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11688bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11689bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
116903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
116919c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11692d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
116960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
116970dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
116980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
116990e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117005d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
117010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
117020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
117030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
117040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
117050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
117070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117085d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
117095d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
117100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
117110dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
117120dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
117130dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11714aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11715aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11716aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
117170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
117190e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
117200e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
117210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117220e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
117230e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
117240e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
117250e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117260e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
117270e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
117280e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117290e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11730104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
117310e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
117320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1173326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1173426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11735a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1173626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1173726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1173826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1173926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1174026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1174126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1174226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1174326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11744fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  mng_info->ping_exclude_tIME=MagickFalse;
11745a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1174626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1174726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1174826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1174926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
117508d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
117518d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11752092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:preserve-colormap");
117538d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
117548b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:preserve-colormap");
117558d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
117568d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
117578d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11758ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  mng_info->ping_preserve_iCCP=MagickFalse;
11759ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11760ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  value=GetImageOption(image_info,"png:preserve-iCCP");
11761ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value == NULL)
11762ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     value=GetImageArtifact(image,"png:preserve-iCCP");
11763ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value != NULL)
11764ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     mng_info->ping_preserve_iCCP=MagickTrue;
11765ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11766ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  /* These compression-level, compression-strategy, and compression-filter
117671868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
117681868258559ddf946fa73ef72dd43507b32623705glennrp   */
11769092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-level");
117701868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
117718b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-level");
117721868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
117731868258559ddf946fa73ef72dd43507b32623705glennrp  {
117741868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
117751868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
117761868258559ddf946fa73ef72dd43507b32623705glennrp       */
117771868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
117781868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
117791868258559ddf946fa73ef72dd43507b32623705glennrp
117800ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
117811868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
117821868258559ddf946fa73ef72dd43507b32623705glennrp
117831868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
117841868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
117851868258559ddf946fa73ef72dd43507b32623705glennrp
117861868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
117871868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
117881868258559ddf946fa73ef72dd43507b32623705glennrp
117891868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
117901868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
117911868258559ddf946fa73ef72dd43507b32623705glennrp
117921868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
117931868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
117941868258559ddf946fa73ef72dd43507b32623705glennrp
117951868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
117961868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
117971868258559ddf946fa73ef72dd43507b32623705glennrp
117981868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
117991868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
118001868258559ddf946fa73ef72dd43507b32623705glennrp
118011868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
118021868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
118031868258559ddf946fa73ef72dd43507b32623705glennrp
118041868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
118051868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
118061868258559ddf946fa73ef72dd43507b32623705glennrp
118071868258559ddf946fa73ef72dd43507b32623705glennrp      else
1180816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118091868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118101868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
118111868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118121868258559ddf946fa73ef72dd43507b32623705glennrp    }
118131868258559ddf946fa73ef72dd43507b32623705glennrp
11814092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-strategy");
118151868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118168b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-strategy");
118171868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118181868258559ddf946fa73ef72dd43507b32623705glennrp  {
118191868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118201868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
118211868258559ddf946fa73ef72dd43507b32623705glennrp
118221868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
118231868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
118241868258559ddf946fa73ef72dd43507b32623705glennrp
118251868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118261868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
118271868258559ddf946fa73ef72dd43507b32623705glennrp
118281868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1182998c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
118301868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1183198c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1183298c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1183398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
118341868258559ddf946fa73ef72dd43507b32623705glennrp
118351868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1183698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
118371868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1183898c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1183998c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1184098c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
118411868258559ddf946fa73ef72dd43507b32623705glennrp
118421868258559ddf946fa73ef72dd43507b32623705glennrp      else
1184316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118441868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118451868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
118461868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118471868258559ddf946fa73ef72dd43507b32623705glennrp    }
118481868258559ddf946fa73ef72dd43507b32623705glennrp
11849092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-filter");
118501868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118518b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-filter");
118521868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118531868258559ddf946fa73ef72dd43507b32623705glennrp  {
118541868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
118551868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
118561868258559ddf946fa73ef72dd43507b32623705glennrp       *
118571868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
118581868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
118591868258559ddf946fa73ef72dd43507b32623705glennrp       */
118601868258559ddf946fa73ef72dd43507b32623705glennrp
118611868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118621868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
118631868258559ddf946fa73ef72dd43507b32623705glennrp
11864b19b8125320afb5954bd73b82d00700e8ed9e984cristy      else if (LocaleCompare(value,"1") == 0)
118651868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
118661868258559ddf946fa73ef72dd43507b32623705glennrp
118671868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118681868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
118691868258559ddf946fa73ef72dd43507b32623705glennrp
118701868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118711868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
118721868258559ddf946fa73ef72dd43507b32623705glennrp
118731868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118741868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
118751868258559ddf946fa73ef72dd43507b32623705glennrp
118761868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118771868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
118781868258559ddf946fa73ef72dd43507b32623705glennrp
118791868258559ddf946fa73ef72dd43507b32623705glennrp      else
1188016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118811868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118821868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
118831868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118841a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  }
1188503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
118861a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  for (source=0; source<8; source++)
118875c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
118881a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    value = NULL;
11889acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
118902dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 0)
118912dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunks");
118922dd1906783a5ece58a6105b4f59239e28b13caddglennrp
118932dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 1)
118942dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunks");
118952dd1906783a5ece58a6105b4f59239e28b13caddglennrp
118962dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 2)
118972dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunk");
118982dd1906783a5ece58a6105b4f59239e28b13caddglennrp
118992dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 3)
119002dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunk");
119012dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119022dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 4)
119032dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunks");
119042dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119052dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 5)
119062dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunks");
119072dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119082dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 6)
119092dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunk");
119102dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119112dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 7)
119122dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunk");
1191326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
119141a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (value == NULL)
119151a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp       continue;
119161a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp
119171a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (source < 4)
119181a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickTrue;
119191a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    else
119201a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickFalse;
1192126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1192203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
119232cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
119241a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        if (source == 0 || source == 2)
119251a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119261a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:exclude-chunk=%s found in image options.\n", value);
119271a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 1 || source == 3)
119282cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119292cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
119301a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 4 || source == 6)
119312cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119321a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image options.\n", value);
119331a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else /* if (source == 5 || source == 7) */
119341a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119351a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
119362cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1193703812ae402fb53d548f0e1d7d14720768f803c2dglennrp
119381a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (IsOptionMember("all",value) != MagickFalse)
119391a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
119401a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_bKGD=excluding;
119411a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_cHRM=excluding;
119421a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_date=excluding;
119431a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_EXIF=excluding;
119441a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_gAMA=excluding;
119451a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_iCCP=excluding;
119461a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=excluding; */
119471a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_oFFs=excluding;
119481a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_pHYs=excluding;
119491a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_sRGB=excluding;
119501a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tEXt=excluding;
11951fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding;
119521a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tRNS=excluding;
119531a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_vpAg=excluding;
119541a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zCCP=excluding;
119551a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zTXt=excluding;
119561a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
11957280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp
11958689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("none",value) != MagickFalse)
119591a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
11960a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_bKGD=excluding != MagickFalse ? MagickFalse :
11961a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11962a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_cHRM=excluding != MagickFalse ? MagickFalse :
11963a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11964a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_date=excluding != MagickFalse ? MagickFalse :
11965a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11966a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_EXIF=excluding != MagickFalse ? MagickFalse :
11967a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11968a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_gAMA=excluding != MagickFalse ? MagickFalse :
11969a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11970a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_iCCP=excluding != MagickFalse ? MagickFalse :
11971a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
119721a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=!excluding; */
11973a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_oFFs=excluding != MagickFalse ? MagickFalse :
11974a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11975a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_pHYs=excluding != MagickFalse ? MagickFalse :
11976a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11977a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_sRGB=excluding != MagickFalse ? MagickFalse :
11978a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11979a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tEXt=excluding != MagickFalse ? MagickFalse :
11980a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11981fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding != MagickFalse ? MagickFalse :
11982fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          MagickTrue;
11983a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tRNS=excluding != MagickFalse ? MagickFalse :
11984a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11985a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_vpAg=excluding != MagickFalse ? MagickFalse :
11986a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11987a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zCCP=excluding != MagickFalse ? MagickFalse :
11988a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11989a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zTXt=excluding != MagickFalse ? MagickFalse :
11990a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
119911a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
1199203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
11993689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("bkgd",value) != MagickFalse)
119941a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_bKGD=excluding;
119952cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11996689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("chrm",value) != MagickFalse)
119971a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_cHRM=excluding;
11998a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11999689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("date",value) != MagickFalse)
120001a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_date=excluding;
120012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12002689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("exif",value) != MagickFalse)
120031a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_EXIF=excluding;
120042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12005689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("gama",value) != MagickFalse)
120061a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_gAMA=excluding;
120072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12008689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("iccp",value) != MagickFalse)
120091a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iCCP=excluding;
120102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12011689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
12012689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("itxt",value) != MagickFalse)
120131a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iTXt=excluding;
12014689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
120152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12016689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("offs",value) != MagickFalse)
120171a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_oFFs=excluding;
120182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12019689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("phys",value) != MagickFalse)
120201a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_pHYs=excluding;
120212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12022689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("srgb",value) != MagickFalse)
120231a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_sRGB=excluding;
120242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12025689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("text",value) != MagickFalse)
120261a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tEXt=excluding;
120272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12028fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (IsOptionMember("time",value) != MagickFalse)
12029fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      mng_info->ping_exclude_tIME=excluding;
12030fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
12031689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("trns",value) != MagickFalse)
120321a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tRNS=excluding;
12033a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
12034689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("vpag",value) != MagickFalse)
120351a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_vpAg=excluding;
120362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12037689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("zccp",value) != MagickFalse)
120381a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zCCP=excluding;
120392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12040689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("ztxt",value) != MagickFalse)
120411a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zTXt=excluding;
1204226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1204326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
120441a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  if (logging != MagickFalse)
1204526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1204626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120475d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1204826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1204926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1205026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1205126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1205226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1205326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
12054a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
12055a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12056a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1205726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1205826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1205926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1206026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1206126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1206226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1206326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1206426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1206526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
12066689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
1206726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1206826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1206926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
12070689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
12071689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp
1207226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1207326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1207426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1207526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1207626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1207726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1207826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1207926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1208126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1208226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
12084fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (mng_info->ping_exclude_tIME != MagickFalse)
12085fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12086fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          "    tIME");
12087a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
12088a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12089a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1209026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1209126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1209326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1209426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1209626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1209726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1209926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1210026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
12101b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
121023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1210316ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
121043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
121060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
121090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
121113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
121123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
121143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
121163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1211716ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
121183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
121193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
121203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
121213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
121233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
121243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1212603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
121273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
121283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
121303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
121313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
121333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
121343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
121353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
121363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
121383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
121393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
121403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
121413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
121423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12143bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1214459575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
121453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
121463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
12148fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
121493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
121513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
121523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
121533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
1215617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     image_info->type==TrueColorMatteType || image->alpha_trait != UndefinedPixelTrait;
121573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121584b917593e694424be469d250448c05c878663812glennrp  jng_alpha_sample_depth = 0;
121594b917593e694424be469d250448c05c878663812glennrp
1216059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1216159575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1216259575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1216359575fa5c228308a41d7f5028390be2083aaaf6dglennrp
12164750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1216559575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1216659575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1216759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1216859575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
121693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12170d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  length=0;
12171d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
121728fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
121733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
121750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
121773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
121783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1217916ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
121800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
121820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
121843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
121850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
121873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
121883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
121890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1219016ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
121923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
121933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
121948a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      jpeg_image->alpha_trait=UndefinedPixelTrait;
121958f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1219616ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1219716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
121983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
121993b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy      (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
122003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
122013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1220259575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1220359575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1220459575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1220559575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1220659575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1220759575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
122083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
122103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
122123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
122137fb2652ba366fc984d1dbb0c66560b91c57dab78cristy    TrueColorType && IsImageGray(image,exception))
122143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1221659575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1221759575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1221859575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1221959575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1222059575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1222159575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
122228fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (transparent != 0)
1222359575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1222459575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1222559575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1222659575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1222759575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1222859575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1222959575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1223059575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1223159575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1223259575fa5c228308a41d7f5028390be2083aaaf6dglennrp
122338fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
122343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
122363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
122383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
122393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1224016ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
122413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1224216ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
122463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
122483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
122493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12251cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
12252cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
12253cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
122543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1225516ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1225816ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
122593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
122603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
122613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1226416ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
122653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1226716ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
122703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
122753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1227616ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
122780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12281e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
12282e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
122863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
122873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
122883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
122893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
122903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
122923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
122933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1229403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
122954e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
122964e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
122973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
122983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
122993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
123003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
123013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
123033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
123043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
123053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
123063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12310f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
123110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12313f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
123140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
123170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
123200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
123230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
123260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
123290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
123320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
123350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
12341cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
123423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
123453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123478fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
123483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
123493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
123503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
123513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
123523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
123553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
123563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
123573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12358bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
123593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
123603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
123623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
123633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
12365bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1236703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
123683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
123693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
123723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
123743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
123763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
123803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
123833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
123853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
123863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
123873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1238803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
123890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
12391e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12392cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12393e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
123940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12396e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12397cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12398e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
123990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
124013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
124043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
124063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
124093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
124113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1241203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1241335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
124143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
124153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
124163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
124193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
124203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
124263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1242903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
124303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1243135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1243235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
124333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1243435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1243535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
124363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1243735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1243835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1244035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1244135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1244716ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
124483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
124513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
124533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1245403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
124553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
124563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1245735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1245816ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
124590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1246035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1246116ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
124620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
124643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
124693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1247035ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1247116ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
124720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1247335ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1247416ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
124750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
124773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
124780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
124803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1248116ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1248216ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
124833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
124843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
124853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
124873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
124883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
124943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
124963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1249703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12498bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12499bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
125003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
125013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
125053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1250803812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
125093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
125103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
125113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
125123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
125133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125178fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
125203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12521bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
125223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12524fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy          size_t
125253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
125263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
125283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12530e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12531f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
125323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12536bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
125373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
125385389e5ad63c880fe6885e3b24c76acbdbf63bd61cristy            len=(size_t) (*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
125393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
125400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12544fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image,len);
12545fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                LogPNGChunk(logging,mng_IDAT,len);
12546fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlob(image,len+4,p);
12547fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image, crc32(0,p,(uInt) len+4));
125483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
125533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12554e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12555e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
125563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
125583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
125633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12565e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12566bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
125673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1256803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
125693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
125713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
125723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
125733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
125763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
125793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
125833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
125843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
125873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
125893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1259016ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
125943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
125963b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1260016ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12604e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12605e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
126063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
126083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
126090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1261059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1261159575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
126123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
126133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
126140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
126180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1261916ea139d53d867211d3bb0fa859a83de653f687ecristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,exception);
126200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
126233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12624e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12625e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
126263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12628e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
126293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
126333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1263403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
126353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
126373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
126383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
126403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
126423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
126433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12645cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
126463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
126483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
126493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1265003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
126513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
126533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
126570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
126593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
126683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
126783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1267916ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1268016ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
126833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1268816ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1268916ea139d53d867211d3bb0fa859a83de653f687ecristy%
126903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1269216ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1269316ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1269621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1269703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
126983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
126993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
127053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
127073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
127103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12711fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1271216ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
127133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
127143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
127153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
127183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1272073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
127213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
127223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
127283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
127293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1273216ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
127333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
127343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
127363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
127373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
127383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
127393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1274316ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1274416ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1275321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
127543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1275603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1275703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1275803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
127693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
127753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
127773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
127783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
127803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
127833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12786bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12789bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12793d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
127943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
127973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
128013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
128033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
128043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
128063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12807fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1280816ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
128113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
128143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1281673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
128193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
128213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
128253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
128263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
128293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
128323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
128373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
128413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
128453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
128473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
128483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
128523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128562dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "  Checking input image(s)\n"
128572dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    Image_info depth: %.20g,    Type: %d",
128582dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) image_info->depth, image_info->type);
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
128630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12865280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           "    Scene: %.20g\n,   Image depth: %.20g",
12866280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           (double) scene++, (double) p->depth);
128670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1286817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (p->alpha_trait != UndefinedPixelTrait)
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
128710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
128750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
128790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
128830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
128853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12886e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
128870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
128910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
128933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
128963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
128983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
129003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
129013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
129033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
129043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
129053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
129063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
129093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
129113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
129123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
129133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
129163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
129203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
129243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
129263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
129283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
129293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
129303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
129313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
129323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
129343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
129363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
129373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
129393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
129403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
129423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
129433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
129443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
129540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
129563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
129573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
129580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
129603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
129610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1296217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (next_image->alpha_trait != UndefinedPixelTrait)
129633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
129640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
1296617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy          if ((next_image->alpha_trait != UndefinedPixelTrait) ||
12967dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy               next_image->page.x || next_image->page.y ||
129683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
129710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
129740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
129760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
129783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
129793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
129800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
129823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
129833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
129843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
129853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
1298617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (image->alpha_trait != UndefinedPixelTrait)
129873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
129880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
129903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129917fb2652ba366fc984d1dbb0c66560b91c57dab78cristy            if (IsImageGray(image,exception) == MagickFalse)
129923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
129963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
129973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
129983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
130043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
130063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
130073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
130080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
130103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
130110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
130133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
130150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1301716ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1301816ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
130193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
130200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
130243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
130253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
130263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
130283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
130293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
130303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
130313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
130323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
130333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
130353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
130363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
130373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
130383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
130393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
130403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
130413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
130433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
130443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
130453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
130463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
130473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
130483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
130493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
130503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
130513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
130533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
130573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
130580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
130603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
130613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
130623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
130633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
130653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
130663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
130673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
130703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
130720261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
13073d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
13074d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1307516ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1307616ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
13077d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
13078d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
13079d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
130803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
130813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
130823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
130833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
130843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
13085cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
13086cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
130873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
130883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
130890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
130913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
130920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
130943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
130950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
130973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
13098d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp            (final_delay != 25) && (final_delay != 50) && (1UL*final_delay !=
130993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
131003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
131013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
131043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
131073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
131083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
131123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
131143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
131153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1311603812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
131174e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
131184e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
131193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
131203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
131213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
131223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
131233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
131243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
131290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
131380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
131413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
131500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
131533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
131590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
131623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
131653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
13166092ec8d083fedaedfb7792995e7ea42164553cffcristy     option=GetImageOption(image_info,"mng:need-cacheoff");
131673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
131683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
131703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
131713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
131733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
131743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
131753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
131763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
13177bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1317803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
131793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
131803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
131813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
131823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
131843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
131853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
131863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
131883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
131893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
131903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
131913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1319203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
131933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
131943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
131953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
131963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
131970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
131993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
132000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
132023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
132030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
132053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13207e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
13208e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
132090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
132113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13212e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
132130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13216e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
132173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
132193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
132203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
132223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
132233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
132243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
132253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
132263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
132293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
132313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1323203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
132330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
13235e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13236cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13237e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
132380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
13240e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13241cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13242cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
132430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
132453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
132463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
132473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
132503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
132523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
132553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
132563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
132573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1325803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1325935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
132603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
132613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
132623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
132633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
132653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
132673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
132683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
132713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
132723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
132733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1327403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
132753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1327635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1327735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
132783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1327935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1328035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
132813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1328235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1328335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
132843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1328535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1328635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
132873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
132883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
132893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
132903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1329216ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
132933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
132963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
132983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1329903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
133000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
133023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1330335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1330416ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
133050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1330635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1330716ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
133080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
133103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
133133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
133153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1331635ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1331716ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
133180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1331935ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1332016ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
133210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
133233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
133263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1332716ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1332816ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
133293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
133303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
133333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
133343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
133363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
133373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
133383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
1333917f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     if (write_mng && ((image->alpha_trait != UndefinedPixelTrait) ||
13340dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy         image->page.x > 0 || image->page.y > 0 || (image->page.width &&
133413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
133423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
133433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
133443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
133463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1334703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
133483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
133493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
133503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
133513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
133523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
133533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
133543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
133553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
133563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
133573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
133593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1336003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
133613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
133623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
133633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
133673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
133683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
133693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
133703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
13371bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
133723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
133733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
133763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
133783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
133793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1338003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
133810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13382bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
133833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1338416ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1338516ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1338616ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1338716ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1338816ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1338916ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
133903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
133910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
133933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
133943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
133953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
133973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
133983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
133993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
134003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
134033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
134053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
134063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
134073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
134083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
134113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
134123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
134133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
134143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
134153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
134163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
134173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
134193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
134203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
134213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
134223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
134233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
134243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
134253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
134263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
134273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
134283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
13429bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
134303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
134313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
134333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
134343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1343503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
134360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13437bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
134383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
134393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
134403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
134413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
134423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
134430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
134453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
134463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
134473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
134483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
134493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
134523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
134533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
134553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13456bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
134573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
134583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
134593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
134613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
134633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
134643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
134683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
134693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
134713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
134723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
134733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
134753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1347603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
134773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
134783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
134793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
134803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
134813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
134823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
134833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
134843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
134853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
134873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
134883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
134903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
134923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
134933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
134953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
134963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
134973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
134983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
134993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
135023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
135043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1350503812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
135063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
135083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
135093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
135113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
135143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
135163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1351703812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
135183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
135203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
135213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
135223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
135233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
135243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
135253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
135263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
135273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
135283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
135294e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
135303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
135323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
135353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
135363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
135383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
135393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
135433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
135443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
135453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1354616ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
135473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
135483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
135503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
135513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
135552f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13556b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
135578d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
135582f2e514554975d510c88df54de98c6cdc1080f1cglennrp
135592f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
135602f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
135612f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13562a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
135632f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
135642f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
135652f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
135662f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
135672f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
135682f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
135692f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
135702f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13571a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
135722f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
135732f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
135742f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
135752f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1357616ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
135773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
135803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
135813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
135823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
135833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
135843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
135853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
135863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
135873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
135883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
135893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
135903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
135910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
135923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
135933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
135940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
135953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
135960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
135973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
135983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
135993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
136003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
136013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
136023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
136033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
136043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
136053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1360603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
136073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
136083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
136093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
136103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
136113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
136123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
136133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
136143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
136150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
136173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
136180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
136203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13621d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1362239992b4dd9b12ef752d55b8e402c069698851f72glennrp
136233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
136243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136253bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
136263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
136273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
136280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
136303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
136313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1363239992b4dd9b12ef752d55b8e402c069698851f72glennrp
136333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
136343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
136363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13637d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
136383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13639