png.c revision c1e07709d63f88437cf56ddbc6b3889a96711346
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[] =
1416647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp{
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
1353151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            msg[MagickPathExtent];
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1355151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) FormatLocaleString(msg,MagickPathExtent,
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)
2183057a5d2cf6f95e2fbea1dc2abec0bc9463f77052dirk        {
2184057a5d2cf6f95e2fbea1dc2abec0bc9463f77052dirk          const char
2185057a5d2cf6f95e2fbea1dc2abec0bc9463f77052dirk            *option;
2186057a5d2cf6f95e2fbea1dc2abec0bc9463f77052dirk
2187057a5d2cf6f95e2fbea1dc2abec0bc9463f77052dirk          option=GetImageOption(image_info,"png:preserve-corrupt-image");
2188057a5d2cf6f95e2fbea1dc2abec0bc9463f77052dirk          if (IsStringTrue(option) == MagickFalse)
2189057a5d2cf6f95e2fbea1dc2abec0bc9463f77052dirk            image->columns=0;
2190057a5d2cf6f95e2fbea1dc2abec0bc9463f77052dirk        }
21910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2194edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2195edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
2196edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
2197edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
2198edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
2199edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2200868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
2201edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
2202edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
2203edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2204943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
2205a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
2206a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
2207a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
2208a3a5f956194e91458e2789966ad15308e8f3df47glennrp
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2212faa852bad40107edae19405e76a299057668d795glennrp
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
22150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2238e604a757f40a91c286711c49577eeced17ea97adglennrp  {
2239e604a757f40a91c286711c49577eeced17ea97adglennrp    const char
2240e604a757f40a91c286711c49577eeced17ea97adglennrp      *value;
2241e604a757f40a91c286711c49577eeced17ea97adglennrp
2242e604a757f40a91c286711c49577eeced17ea97adglennrp    value=GetImageOption(image_info,"profile:skip");
2243e604a757f40a91c286711c49577eeced17ea97adglennrp
2244e604a757f40a91c286711c49577eeced17ea97adglennrp    if (IsOptionMember("ICC",value) == MagickFalse)
2245e604a757f40a91c286711c49577eeced17ea97adglennrp    {
2246e604a757f40a91c286711c49577eeced17ea97adglennrp
2247e604a757f40a91c286711c49577eeced17ea97adglennrp       value=GetImageOption(image_info,"png:preserve-iCCP");
2248e604a757f40a91c286711c49577eeced17ea97adglennrp
2249e604a757f40a91c286711c49577eeced17ea97adglennrp       if (value == NULL)
2250e604a757f40a91c286711c49577eeced17ea97adglennrp          value=GetImageArtifact(image,"png:preserve-iCCP");
2251e604a757f40a91c286711c49577eeced17ea97adglennrp
2252e604a757f40a91c286711c49577eeced17ea97adglennrp       if (value != NULL)
2253e604a757f40a91c286711c49577eeced17ea97adglennrp          ping_preserve_iCCP=MagickTrue;
2254201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp
2255201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp#if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED)
2256201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp       /* Don't let libpng check for ICC/sRGB profile because we're going
2257201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp        * to do that anyway.  This feature was added at libpng-1.6.12.
2258cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp        * If logging, go ahead and check and issue a warning as appropriate.
2259201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp        */
2260cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp       if (logging == MagickFalse)
2261cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp          png_set_option(ping, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON);
2262201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp#endif
2263e604a757f40a91c286711c49577eeced17ea97adglennrp    }
2264e604a757f40a91c286711c49577eeced17ea97adglennrp#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
2265e604a757f40a91c286711c49577eeced17ea97adglennrp    else
2266e604a757f40a91c286711c49577eeced17ea97adglennrp    {
2267e604a757f40a91c286711c49577eeced17ea97adglennrp       png_set_keep_unknown_chunks(ping, 1, mng_iCCP, 1);
2268e604a757f40a91c286711c49577eeced17ea97adglennrp    }
2269e604a757f40a91c286711c49577eeced17ea97adglennrp#endif
2270e604a757f40a91c286711c49577eeced17ea97adglennrp  }
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
22732ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#if PNG_LIBPNG_VER < 10700 /* Avoid libpng16 warning */
22742ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp  png_set_keep_unknown_chunks(ping, 2, NULL, 0);
22752ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#else
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
22772ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#endif
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22852feb141b6f74ce425fed3272286fab1f50366bb9glennrp#ifdef PNG_SET_USER_LIMITS_SUPPORTED
228609cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  if (PNG_LIBPNG_VER >= 10400)
22872feb141b6f74ce425fed3272286fab1f50366bb9glennrp    /* Limit the size of the chunk storage cache used for sPLT, text,
2288687361928f16a28ea56e200d00e970e68173cc25glennrp     * and unknown chunks.
22892feb141b6f74ce425fed3272286fab1f50366bb9glennrp     */
2290687361928f16a28ea56e200d00e970e68173cc25glennrp    png_set_chunk_cache_max(ping, 32767);
229109cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  endif
22922feb141b6f74ce425fed3272286fab1f50366bb9glennrp#endif
22932feb141b6f74ce425fed3272286fab1f50366bb9glennrp
22949bf97b6c2143eb20c330346b01e82102cc082725glennrp#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
22959bf97b6c2143eb20c330346b01e82102cc082725glennrp    /* Disable new libpng-1.5.10 feature */
22969bf97b6c2143eb20c330346b01e82102cc082725glennrp    png_set_check_for_invalid_index (ping, 0);
22979bf97b6c2143eb20c330346b01e82102cc082725glennrp#endif
22989bf97b6c2143eb20c330346b01e82102cc082725glennrp
2299991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2300991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2301991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2315991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2319faa852bad40107edae19405e76a299057668d795glennrp
2320faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2321faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2322faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2323faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2324faa852bad40107edae19405e76a299057668d795glennrp
2325fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp  ping_file_depth = ping_bit_depth;
2326fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp
23270d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  /* Swap bytes if requested */
23280d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  if (ping_file_depth == 16)
23290d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  {
23300d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp     const char
2331a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp       *value;
23326647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
2333a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     value=GetImageOption(image_info,"png:swap-bytes");
23346647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
2335a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value == NULL)
2336a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        value=GetImageArtifact(image,"png:swap-bytes");
23376647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
2338a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value != NULL)
2339a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        png_set_swap(ping);
23400d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  }
23410d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp
23425830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  /* Save bit-depth and color-type in case we later want to write a PNG00 */
23435830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  {
23445830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      char
2345151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        msg[MagickPathExtent];
23465830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2347151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(msg,MagickPathExtent,"%d",(int) ping_color_type);
23483398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.color-type-orig",msg,exception);
23495830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2350151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(msg,MagickPathExtent,"%d",(int) ping_bit_depth);
23513398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.bit-depth-orig",msg,exception);
23525830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  }
23535830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2354faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2355faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2356faa852bad40107edae19405e76a299057668d795glennrp
2357faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2358faa852bad40107edae19405e76a299057668d795glennrp
2359faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2361fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       png_set_packing(ping);
2362fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       ping_bit_depth = 8;
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2364faa852bad40107edae19405e76a299057668d795glennrp
2365faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2367faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
236898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2369176b29a003f11fd934137871d574995319408665cristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2370176b29a003f11fd934137871d574995319408665cristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2371176b29a003f11fd934137871d574995319408665cristy    {
2372176b29a003f11fd934137871d574995319408665cristy      image->rendering_intent=UndefinedIntent;
237398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      intent=Magick_RenderingIntent_to_PNG_RenderingIntent(UndefinedIntent);
2374176b29a003f11fd934137871d574995319408665cristy      (void) ResetMagickMemory(&image->chromaticity,0,
2375176b29a003f11fd934137871d574995319408665cristy        sizeof(image->chromaticity));
2376176b29a003f11fd934137871d574995319408665cristy    }
237798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23812dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG width: %.20g, height: %.20g\n"
23822dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG color_type: %d, bit_depth: %d\n"
23832dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG compression_method: %d\n"
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
23852dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) ping_width, (double) ping_height,
23862dd1906783a5ece58a6105b4f59239e28b13caddglennrp        ping_color_type, ping_bit_depth,
23872dd1906783a5ece58a6105b4f59239e28b13caddglennrp        ping_compression_method,
2388faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
23892dd1906783a5ece58a6105b4f59239e28b13caddglennrp
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2392ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (png_get_valid(ping,ping_info, PNG_INFO_iCCP))
2393ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {
2394ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_iCCP=MagickTrue;
2395ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      if (logging != MagickFalse)
2396ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2397ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG iCCP chunk.");
2398ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    }
2399ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
240098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
240198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
240298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_gAMA=MagickTrue;
240398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
240498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
240598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG gAMA chunk.");
240698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
240798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
240898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
240998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
241098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_cHRM=MagickTrue;
241198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
241298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
241398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG cHRM chunk.");
241498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
241598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2416ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (ping_found_iCCP != MagickTrue && png_get_valid(ping,ping_info,
2417ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      PNG_INFO_sRGB))
241898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
2419ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_sRGB=MagickTrue;
242098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
242198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2422ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG sRGB chunk.");
242398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
242498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2425ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2426e604a757f40a91c286711c49577eeced17ea97adglennrp    if (ping_found_iCCP !=MagickTrue &&
2427ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_sRGB != MagickTrue &&
2428ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info, PNG_INFO_iCCP))
242998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
2430ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_iCCP=MagickTrue;
243198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
243298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2433ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG iCCP chunk.");
243498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
243598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2436faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2441e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2442e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2443e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2444e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2445e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2446e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2447e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2448e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
24570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
2466ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2467e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          profile=BlobToStringInfo(info,profile_length);
2468ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2469e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          if (profile == (StringInfo *) NULL)
2470ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          {
2471ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            png_warning(ping, "ICC profile is NULL");
2472ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            profile=DestroyStringInfo(profile);
2473ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          }
2474ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          else
2475ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          {
2476ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            if (ping_preserve_iCCP == MagickFalse)
2477edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2478ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 int
2479ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
2480ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
2481ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2482ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2483ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 png_uint_32
2484ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   length,
2485ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
2486ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2487ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 unsigned char
2488ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   *data;
2489ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2490ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
2491ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2492ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
2493ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 {
2494ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
2495ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   {
2496ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
2497ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
2498ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2499ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
2500ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                         (unsigned long) length);
2501ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2502ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
2503ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
2504ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2505ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2506ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
2507ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
2508ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
2509ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2510ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
2511ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
2512ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2513ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
2514ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
2515ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
2516ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        if (image->rendering_intent==UndefinedIntent)
2517ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
2518ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
2519ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
2520ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
2521ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
2522ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        break;
2523ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
2524ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   }
2525ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 }
2526ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
2527ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 {
2528ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2529ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
2530ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        (unsigned long) length);
2531ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) SetImageProfile(image,"icc",profile,exception);
2532ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 }
2533edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2534ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            else /* Preserve-iCCP */
2535edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2536ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) SetImageProfile(image,"icc",profile,exception);
2537edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2538ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2539ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            profile=DestroyStringInfo(profile);
2540ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          }
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2544ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2547ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    if (ping_found_iCCP==MagickFalse && png_get_valid(ping,ping_info,
2548ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        PNG_INFO_sRGB))
2549ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {
2550ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      if (png_get_sRGB(ping,ping_info,&intent))
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2552ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        if (image->rendering_intent == UndefinedIntent)
2553ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          image->rendering_intent=
2554ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             Magick_RenderingIntent_from_PNG_RenderingIntent (intent);
25550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2558e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2560ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    }
2561ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2562ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    else if (mng_info->have_global_srgb)
2563ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      {
2564ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        if (image->rendering_intent == UndefinedIntent)
2565ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          image->rendering_intent=
2566ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            Magick_RenderingIntent_from_PNG_RenderingIntent
2567ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            (mng_info->global_srgb_intent);
2568ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      }
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2571ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2572ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2574faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2575faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2576faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
25770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
258698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2587faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2588faa852bad40107edae19405e76a299057668d795glennrp    {
2589faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2590faa852bad40107edae19405e76a299057668d795glennrp        {
2591faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2592faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2593faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2594faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2595faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2596faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2597faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2598faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2599faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2600faa852bad40107edae19405e76a299057668d795glennrp        }
2601faa852bad40107edae19405e76a299057668d795glennrp    }
26020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2603faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
26140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2615ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp       ping_found_cHRM=MagickTrue;
2616ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
26173d627862fb79aad8a20be4f1587f0b8761db441aglennrp       if (image->chromaticity.red_primary.x>0.6399f &&
26183d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
26193d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
26203d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
26213d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
26223d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
26233d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
26243d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
26253d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
26263d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
26273d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
26283d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
26293d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
26303d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
26313d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
26323d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f)
26333d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_sRGB_cHRM=MagickTrue;
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2636e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26383d627862fb79aad8a20be4f1587f0b8761db441aglennrp      if (ping_found_sRGB != MagickTrue &&
26393d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_gAMA != MagickTrue ||
264084288238d90b2e1831857d6b2427abd7875b7e1bglennrp          (image->gamma > .45 && image->gamma < .46)) &&
26413d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_cHRM != MagickTrue ||
2642cd8b331760407523f2a59cc65c1cd9c3d4422bafcristy          ping_found_sRGB_cHRM != MagickFalse) &&
26433d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_iCCP != MagickTrue)
26445cf1bff142633838354b1080183c957900bc80e8glennrp      {
26455cf1bff142633838354b1080183c957900bc80e8glennrp         png_set_sRGB(ping,ping_info,
26465cf1bff142633838354b1080183c957900bc80e8glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent
26475cf1bff142633838354b1080183c957900bc80e8glennrp            (image->rendering_intent));
26485cf1bff142633838354b1080183c957900bc80e8glennrp         file_gamma=1.000f/2.200f;
26495cf1bff142633838354b1080183c957900bc80e8glennrp         ping_found_sRGB=MagickTrue;
265084288238d90b2e1831857d6b2427abd7875b7e1bglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2651918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp           "    Setting sRGB as if in input");
26525cf1bff142633838354b1080183c957900bc80e8glennrp      }
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26545cf1bff142633838354b1080183c957900bc80e8glennrp
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2656faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2658905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2659905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
26600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2664e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2665e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2669faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2670faa852bad40107edae19405e76a299057668d795glennrp    {
2671faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2672faa852bad40107edae19405e76a299057668d795glennrp        {
2673faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2674faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2675faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2676faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2677faa852bad40107edae19405e76a299057668d795glennrp        }
2678faa852bad40107edae19405e76a299057668d795glennrp    }
2679faa852bad40107edae19405e76a299057668d795glennrp
26805c97f62ba919c3c109f0072df3b560056565e9e7cristy  x_resolution=0;
26815c97f62ba919c3c109f0072df3b560056565e9e7cristy  y_resolution=0;
26825c97f62ba919c3c109f0072df3b560056565e9e7cristy  unit_type=0;
2683faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
26890881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
269016ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.x=(double) x_resolution;
269116ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.y=(double) y_resolution;
26920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
269616ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.x=(double) x_resolution/100.0;
269716ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.y=(double) y_resolution/100.0;
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2702e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2703e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2706823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2707faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
27130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2715faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
27210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2722faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2723edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              {
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
2726edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                    png_warning(ping,
2727edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                      "global tRNS has more entries than global PLTE");
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2729edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                else
2730edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  {
2731edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                     png_set_tRNS(ping,ping_info,mng_info->global_trns,
2732edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                       (int) mng_info->global_trns_length,NULL);
2733edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  }
2734edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               }
2735bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2740faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2749faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2750faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
27510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
27540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
27570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
27600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2761c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2762c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2763c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2769edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"No global PLTE in file");
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2773bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2774faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2775faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
27770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2778faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2780bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2781bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2782bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
27832dd1906783a5ece58a6105b4f59239e28b13caddglennrp      /* Set image background color.
27842dd1906783a5ece58a6105b4f59239e28b13caddglennrp       * Scale background components to 16-bit, then scale
2785bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2786bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
27872cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2788bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
27890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2790fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth == 1)
2791bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
27920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2793fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 2)
2794bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
27950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2796fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 4)
2797bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
27980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2799fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth <= 8)
2800bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
28012cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2802bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2803bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2804bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
28052cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2806bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2807bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
28082dd1906783a5ece58a6105b4f59239e28b13caddglennrp            if (logging != MagickFalse)
28092dd1906783a5ece58a6105b4f59239e28b13caddglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28102dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 "    Reading PNG bKGD chunk, raw ping_background=(%d,%d,%d).\n"
28112dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 "    bkgd_scale=%d.  ping_background=(%d,%d,%d).",
28122dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->red,ping_background->green,
28132dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->blue,
28142dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 bkgd_scale,ping_background->red,
28152dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->green,ping_background->blue);
2816bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
28172cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2818bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2819faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
28200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2821bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2822faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
28230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2824bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2825bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
28260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
282716ea139d53d867211d3bb0fa859a83de653f687ecristy        image->background_color.alpha=OpaqueAlpha;
28282cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2829bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2830bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2831bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2832bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2833bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2834bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2836bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2837a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2838faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2841a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
284635ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
284735ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
284835ef824baa82511126ff0072ae30eee0da9c05a3cristy
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2853fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      max_sample = (int) ((one << ping_file_depth) - 1);
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2855faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2856faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2857faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2858faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2859faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2860faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
28653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2866faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
28678a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          image->alpha_trait=UndefinedPixelTrait;
28683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2871a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
28729b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp            scale_to_short;
2873a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2874fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale_to_short = 65535L/((1UL << ping_file_depth)-1);
2875a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2876a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2877a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2878a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2879a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
288016ea139d53d867211d3bb0fa859a83de653f687ecristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
288105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2882faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28840f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
28850f111984738842d27d04aed2a3f823d82a943506glennrp              {
28860f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28872dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    Raw tRNS graylevel = %d, scaled graylevel = %d.",
28882dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (int) ping_trans_color->gray,(int) transparent_color.alpha);
28890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28900f111984738842d27d04aed2a3f823d82a943506glennrp              }
289116ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.red=transparent_color.alpha;
289216ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.green=transparent_color.alpha;
289316ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.blue=transparent_color.alpha;
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2900faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2905faa852bad40107edae19405e76a299057668d795glennrp
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2907faa852bad40107edae19405e76a299057668d795glennrp
2908faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2909faa852bad40107edae19405e76a299057668d795glennrp
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2914bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2916bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2919faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2920faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2931faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2932faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2933a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
293416ea139d53d867211d3bb0fa859a83de653f687ecristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
293516ea139d53d867211d3bb0fa859a83de653f687ecristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
29368d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    {
29370a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      double
29380a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp        image_gamma = image->gamma;
29390a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp
29400a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      (void)LogMagickEvent(CoderEvent,GetMagickModule(),
29410a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp         "    image->gamma=%f",(float) image_gamma);
29420a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp
29430a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      if (image_gamma > 0.75)
29448d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        {
29450a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp          /* Set image->rendering_intent to Undefined,
2946e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp           * image->colorspace to GRAY, and reset image->chromaticity.
29478d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp           */
294867429939a9bdca8c2ea541cd690b8e479c921527glennrp          image->intensity = Rec709LuminancePixelIntensityMethod;
29498d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          SetImageColorspace(image,GRAYColorspace,exception);
29508d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        }
2951ccc36af759d30fb50b1deda241d038402a393b17glennrp      else
2952ccc36af759d30fb50b1deda241d038402a393b17glennrp        {
2953ccc36af759d30fb50b1deda241d038402a393b17glennrp          RenderingIntent
2954ccc36af759d30fb50b1deda241d038402a393b17glennrp            save_rendering_intent = image->rendering_intent;
2955ccc36af759d30fb50b1deda241d038402a393b17glennrp          ChromaticityInfo
2956ccc36af759d30fb50b1deda241d038402a393b17glennrp            save_chromaticity = image->chromaticity;
2957ccc36af759d30fb50b1deda241d038402a393b17glennrp
2958ccc36af759d30fb50b1deda241d038402a393b17glennrp          SetImageColorspace(image,GRAYColorspace,exception);
2959ccc36af759d30fb50b1deda241d038402a393b17glennrp          image->rendering_intent = save_rendering_intent;
2960ccc36af759d30fb50b1deda241d038402a393b17glennrp          image->chromaticity = save_chromaticity;
2961ccc36af759d30fb50b1deda241d038402a393b17glennrp        }
2962ccc36af759d30fb50b1deda241d038402a393b17glennrp
2963ccc36af759d30fb50b1deda241d038402a393b17glennrp      image->gamma = image_gamma;
29648d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    }
29656647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
2966e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp  (void)LogMagickEvent(CoderEvent,GetMagickModule(),
29670a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      "    image->colorspace=%d",(int) image->colorspace);
2968a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
2969faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
297032340ffa74550819f755f966e397ed58bbccd8e5glennrp      ((int) ping_bit_depth < 16 &&
297132340ffa74550819f755f966e397ed58bbccd8e5glennrp      (int) ping_color_type == PNG_COLOR_TYPE_GRAY))
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2973befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2974befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2975befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2977befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2978fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      image->colors=one << ping_file_depth;
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
298167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
298267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
298367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
298467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2986faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2992bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
29930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
300516ea139d53d867211d3bb0fa859a83de653f687ecristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
3006edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
30070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3008faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
30140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30156af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30216af6cf1a950b111ad0ac706269a703086693ba71glennrp
302267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
30236af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
30246af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
30256af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
30266af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
30276af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30329b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp          Quantum
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3035d7c4d1cebe0454ec33c82a85c86a2737fc0f2b41cristy          scale = (Quantum) (65535UL)/((1UL << ping_file_depth)-1);
30360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30379b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
30389b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp          scale = ScaleShortToQuantum(scale);
30399b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp#endif
30400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3041bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3049147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3050cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
3051cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
3052147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
3053151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        msg[MagickPathExtent];
3054147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3055fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     /* encode ping_width, ping_height, ping_file_depth, ping_color_type,
3056147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
3057147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3058151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy     (void) FormatLocaleString(msg,MagickPathExtent,
30597cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
30603398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.width,height",msg,exception);
3061147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3062151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy     (void) FormatLocaleString(msg,MagickPathExtent,"%d",(int) ping_file_depth);
30633398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.bit_depth",msg,exception);
3064147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3065151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy     (void) FormatLocaleString(msg,MagickPathExtent,"%d (%s)",
30665dff435eceea4f80207a906b11e65aed48fe3f27glennrp         (int) ping_color_type,
30675dff435eceea4f80207a906b11e65aed48fe3f27glennrp         Magick_ColorType_from_PNG_ColorType((int)ping_color_type));
30683398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.color_type",msg,exception);
3069147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3070913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (ping_interlace_method == 0)
3071913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3072151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%d (Not interlaced)",
3073913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3074913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3075913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else if (ping_interlace_method == 1)
3076913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3077151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%d (Adam7 method)",
3078913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3079913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3080913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else
3081913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3082151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%d (Unknown method)",
3083913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3084913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3085913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
3086913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp
3087913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (number_colors != 0)
3088913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3089151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%d",
3090913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) number_colors);
30913398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:PLTE.number_colors",msg,
3092913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            exception);
3093913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
309439d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp   }
3095fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
309639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp   read_tIME_chunk(image,ping,ping_info,exception);
3097fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
309839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
3099147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
31050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31060ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
3107347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
3108347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31101b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
31111b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
31121b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
31131b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3116e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3119edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3120868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3121cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3123edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
31270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
31340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
31360997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(image->rows,ping_rowbytes*
3137cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
31380997332e2c35a821b271d6e7473c01c10dc206adcristy  else
31390997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(ping_rowbytes,sizeof(*ping_pixels));
31400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31410997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
3142edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation failed");
31430997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
31440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31515f766ef8b0cd9906c2c3a56d845828380a251073cristy  quantum_info=AcquireQuantumInfo(image_info,image);
315216ea139d53d867211d3bb0fa859a83de653f687ecristy
315316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
3154edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping,"Failed to allocate quantum_info");
31550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31564b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
31574b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp
3158c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
3159c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3160c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
3161c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
3162c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3163c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
3164c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3167c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
3168c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3169c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
3170c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
3171c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
3172ccc36af759d30fb50b1deda241d038402a393b17glennrp        image->alpha_trait=
3173ccc36af759d30fb50b1deda241d038402a393b17glennrp            (((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
3174c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
3175c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3176b0a657e13c4aefba39c51292005427b47277869dcristy            BlendPixelTrait : UndefinedPixelTrait;
31770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3178c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
3179c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
3180c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
3181c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
31820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3183c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
3184c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
31850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3186cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
3187c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3188c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          if (pass < num_passes-1)
3189c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp            continue;
3190c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3191862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
319316ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
3194c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
31950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
319616ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
319716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
319816ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
31990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320016ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
320116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
320216ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
32030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320416ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
320516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
320616ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
32070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320816ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
320916ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321016ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
32110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
321216ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
321316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321416ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
32153faa9a3fb01696daaf976d595f492cb530bffb21glennrp
3216c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
3217c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3218c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
3219a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
3220a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3221a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
3222a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3223c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3224c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
32255aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
32265aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
322716ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
3228c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
3229a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3230a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3231a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
3232a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3233c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
3234c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
3235c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
32364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
32374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
323816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
323916ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
324016ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
324116ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
324216ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
324316ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
32444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
3245a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3246a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3247a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
32484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
32494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
32504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
325116ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
3252c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
3253c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
32540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3255af9320404a7b05014476f844b11110157a21b73eglennrp          if (num_passes == 1)
3256c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3257af9320404a7b05014476f844b11110157a21b73eglennrp              status=SetImageProgress(image,LoadImageTag,
3258af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) y, image->rows);
32590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3260c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
3261c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
3262c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
3263c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
3264c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
3265c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
32660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3267af9320404a7b05014476f844b11110157a21b73eglennrp        if (num_passes != 1)
32687a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3269c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
32707a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
32717a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
32727a287bfadeadea12e47c2376ca78a5d101687142cristy          }
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3277c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3289c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3290c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3291c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
329216ea139d53d867211d3bb0fa859a83de653f687ecristy
32938a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
3294b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
32950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
3297b0a657e13c4aefba39c51292005427b47277869dcristy        (image->alpha_trait  == BlendPixelTrait?  2 : 1)*
3298b0a657e13c4aefba39c51292005427b47277869dcristy        sizeof(*quantum_scanline));
32990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
3301edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
33020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3303bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33054f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        Quantum
33064f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp           alpha;
33074f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3309faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3310c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3313c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3314cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
3315c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3316c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp        if (pass < num_passes-1)
3317c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          continue;
3318c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
33194f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
33200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
332116ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
33230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3324cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3326c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3327faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33314f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
3332faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3333bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3335a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33364f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33374f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                alpha=ScaleCharToQuantum((unsigned char)*p++);
33384f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33394f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                SetPixelAlpha(image,alpha,q);
33404f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33414f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                if (alpha != OpaqueAlpha)
33420b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
33434f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
334416ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3348bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3349a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
335347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3356bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3357a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
33589b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
335987281ec8d96ad26dfed9968c29b2920cb3d96744cristy              unsigned short
336058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
336158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
336258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3363c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
336458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
336558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3366c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
336758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
336858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3369c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
337058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
33710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3372faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3374c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3375c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3376c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3377c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3378c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3379c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
33804f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33814f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  alpha=ScaleShortToQuantum(quantum);
33824f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  SetPixelAlpha(image,alpha,q);
33834f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33844f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  if (alpha != OpaqueAlpha)
338558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
33864f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
338716ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
338858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
338958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
339058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
339158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
339258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
339347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
339458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
339558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
339616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
33974f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
339816ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
33990b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
34004f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
340158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
340216ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3405a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
340647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
340947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
34133faa9a3fb01696daaf976d595f492cb530bffb21glennrp
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
34180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
341916ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
342016ea139d53d867211d3bb0fa859a83de653f687ecristy
342116ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
342216ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3423bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
342416ea139d53d867211d3bb0fa859a83de653f687ecristy        {
342516ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
342616ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
342716ea139d53d867211d3bb0fa859a83de653f687ecristy        }
34280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
34310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3432af9320404a7b05014476f844b11110157a21b73eglennrp        if (num_passes == 1)
34337a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3434cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
34359fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
343647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34377a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
34387a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
34397a287bfadeadea12e47c2376ca78a5d101687142cristy          }
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3441c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3442af9320404a7b05014476f844b11110157a21b73eglennrp      if (num_passes != 1)
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
344547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3449c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3452c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3453b0a657e13c4aefba39c51292005427b47277869dcristy    image->alpha_trait=found_transparent_pixel ? BlendPixelTrait :
3454b0a657e13c4aefba39c51292005427b47277869dcristy      UndefinedPixelTrait;
3455c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3456c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3457c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3458c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3459c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
34625aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
34635aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34645aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3465bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
34665aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
34675aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3468c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3470c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
347116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
347216ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
347316ea139d53d867211d3bb0fa859a83de653f687ecristy
34745c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
34755c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3476b0a657e13c4aefba39c51292005427b47277869dcristy      PixelTrait
3477b0a657e13c4aefba39c51292005427b47277869dcristy        alpha_trait;
34785c6f789db7a30bad01ace12b09ad9cd471339e94cristy
3479b0a657e13c4aefba39c51292005427b47277869dcristy      alpha_trait=image->alpha_trait;
34808a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
348116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3482b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait=alpha_trait;
34835c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
348447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34854eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3487ccc36af759d30fb50b1deda241d038402a393b17glennrp  if (logging != MagickFalse)
3488ccc36af759d30fb50b1deda241d038402a393b17glennrp  {
3489ccc36af759d30fb50b1deda241d038402a393b17glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3490ccc36af759d30fb50b1deda241d038402a393b17glennrp       "  image->storage_class=%d\n",(int) image->storage_class);
3491ccc36af759d30fb50b1deda241d038402a393b17glennrp  }
3492ccc36af759d30fb50b1deda241d038402a393b17glennrp
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3494bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
34970997332e2c35a821b271d6e7473c01c10dc206adcristy      pixel_info=RelinquishVirtualMemory(pixel_info);
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
349916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
3500868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3501cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
350847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3509faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
35188a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=BlendPixelTrait;
3519c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35203c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3521c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
35230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3525c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
35260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
35270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35288a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                 image->colormap[x].alpha_trait=BlendPixelTrait;
352916ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
353016ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
35310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3532c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
353347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
35350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
35360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
35370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
353916ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
35400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
35418a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->colormap[x].alpha_trait=BlendPixelTrait;
354216ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
35430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
35440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
35450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
354616ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
35470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
354847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3549a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3550a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3551a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
35520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
35530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
35550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
35560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
35570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3558c11cf6a442f3046940608a5743a68cc891deb13eglennrp
355916ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
35600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3561c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3563a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3564a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3565a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
35660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
35670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
356816ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
356916ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
357016ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
357116ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
357216ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
357316ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
35744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
357516ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
35764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
35770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
357867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
35790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
35804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
358116ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
35824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3583a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
35840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
358516ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
35860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
35870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
35890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3590c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
35910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3592a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3593c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35963c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3597eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
35984eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
35994eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3600a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3601a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
36024eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3603a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3604a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36064eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
36074eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
36084eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
36094eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
36100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36114eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
36124eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36134eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
36140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36155285ae1de367013bf70a5a4e5feaefe3de8dda7bglennrp        if (strlen(text[i].key) > 16 &&
36166dfc26699a1aacdec9771115c4dcaf6c5c0a8f98glennrp            memcmp(text[i].key, "Raw profile type ",17) == 0)
36174eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
361899f968111025b4fadb966ca482c6f57750bf007bglennrp            const char
361999f968111025b4fadb966ca482c6f57750bf007bglennrp              *value;
362099f968111025b4fadb966ca482c6f57750bf007bglennrp
362199f968111025b4fadb966ca482c6f57750bf007bglennrp            value=GetImageOption(image_info,"profile:skip");
362299f968111025b4fadb966ca482c6f57750bf007bglennrp
362399f968111025b4fadb966ca482c6f57750bf007bglennrp            if (IsOptionMember(text[i].key+17,value) == MagickFalse)
362499f968111025b4fadb966ca482c6f57750bf007bglennrp            {
362599f968111025b4fadb966ca482c6f57750bf007bglennrp               (void) Magick_png_read_raw_profile(ping,image,image_info,text,
362699f968111025b4fadb966ca482c6f57750bf007bglennrp                  (int) i,exception);
362799f968111025b4fadb966ca482c6f57750bf007bglennrp               num_raw_profiles++;
362899f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
362999f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
363099f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Read raw profile %s",text[i].key+17);
363199f968111025b4fadb966ca482c6f57750bf007bglennrp            }
363299f968111025b4fadb966ca482c6f57750bf007bglennrp            else
363399f968111025b4fadb966ca482c6f57750bf007bglennrp            {
363499f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
363599f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
363699f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Skipping raw profile %s",text[i].key+17);
363799f968111025b4fadb966ca482c6f57750bf007bglennrp            }
36384eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
36394eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36404eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
36414eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
36424eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
36434eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
36444eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36454eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
3646151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            value=(char *) AcquireQuantumMemory(length+MagickPathExtent,
36474eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
36484eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
36494eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
3650edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"Memory allocation failed");
36514eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
36524eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
36534eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
36544eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
36554eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36564eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
36574eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
36584eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
36594eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
36604eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
36614eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
366216ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36644eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36664eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36672dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      length: %lu\n"
36682dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      Keyword: %s",
36692dd1906783a5ece58a6105b4f59239e28b13caddglennrp                (unsigned long) length,
36702dd1906783a5ece58a6105b4f59239e28b13caddglennrp                text[i].key);
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36734eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
367497f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
36754eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
3676fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    num_text_total += num_text;
3677fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
36783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
369173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
36920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
369947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
3704edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp             png_error(ping,"Memory allocation failed");
37050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
3707edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping,"Cannot overwrite frozen MNG object buffer");
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
37160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
371816ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
37190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
37220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
3724edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping, "Cloning image for object buffer failed");
37250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3726faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
37280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3729faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3730faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3731faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3732faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3733faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3734faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3735faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3736faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
37370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3738faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
37483c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
375447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37600a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
37618a46d827a124555f0c48fb2368ec1bba8e079ab6cristy   /* Set image->alpha_trait to MagickTrue if the input colortype supports
37620a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
37630a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
37640a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
37658a46d827a124555f0c48fb2368ec1bba8e079ab6cristy    image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
37660a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
37670a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3768b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
37690a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3770224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#if 0  /* I'm not sure what's wrong here but it does not work. */
377117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy    if (image->alpha_trait != UndefinedPixelTrait)
37725830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37735830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3774def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,GrayscaleAlphaType,exception);
37755830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37765830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
3777def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,PaletteAlphaType,exception);
37785830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37795830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
3780def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,TrueColorAlphaType,exception);
37815830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
37825830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37835830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    else
37845830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37855830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
37865830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleType,exception);
37875830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37885830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
37895830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteType,exception);
37905830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37915830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
37925830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorType,exception);
37935830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
3794224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#endif
37955830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
3796cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3797cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3798cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3799151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy       msg[MagickPathExtent];
3800cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38014eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3802cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3803cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
3804151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
3805613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
38063398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:text",msg,
380716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3808cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3809cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3810cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3811cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3812151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
3813cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
381416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
381516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3816cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3817cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
381898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_cHRM != MagickFalse)
38195961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
3820151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%s",
38215961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
38223398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:cHRM",msg,
382316ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38245961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3825cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3826cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
38275961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
3828151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%s",
38295961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
38303398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:bKGD",msg,
383116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38325961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
38335961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
3834151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy     (void) FormatLocaleString(msg,MagickPathExtent,"%s",
38355961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3836cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
383798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#if defined(PNG_iCCP_SUPPORTED)
383898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_iCCP != MagickFalse)
38393398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:iCCP",msg,
384016ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
384198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#endif
3842cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38434eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
38443398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:tRNS",msg,
384516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38464eb3931feb349dd87142c78503b779228f3e1a0fglennrp
38474eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
384898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_sRGB != MagickFalse)
38494eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
3850151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
385198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            "intent=%d (%s)",
385298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            (int) intent,
385398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            Magick_RenderingIntentString_from_PNG_RenderingIntent(intent));
38543398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:sRGB",msg,
385598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp                 exception);
38564eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38574eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38584eb3931feb349dd87142c78503b779228f3e1a0fglennrp
385998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_gAMA != MagickFalse)
38604eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
3861151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
386216ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
386316ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
38643398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:gAMA",msg,
386516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38664eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3867cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38684eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3869cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
38704eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
3871151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
387207523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
38734eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
38743398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:pHYs",msg,
387516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38764eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38774eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3878cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38794eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
38804eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
38814eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
3882151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"x_off=%.20g, y_off=%.20g",
38834eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
38843398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:oFFs",msg,
388516ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38864eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38874eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38884eb3931feb349dd87142c78503b779228f3e1a0fglennrp
3889fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
3890fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk     read_tIME_chunk(image,ping,end_info,exception);
3891fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
3892fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
389307523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
389407523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
389507523c7d2e40370804c2036295571e4b6426f94dglennrp       {
3896151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
389707523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
389807523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
38993398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:vpAg",msg,
390016ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
390107523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3902cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3903cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39090997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
39140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3915868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3916edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
3917edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
3918edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3919edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* }  for navigation to beginning of SETJMP-protected block, revert to
3920edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    Throwing an Exception when an error occurs.
3921edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
3922edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
3931919429921a43880a338ed87e128d3b96219442efglennrp    *image;
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
393421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
393521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
3942151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    magic_number[MagickPathExtent];
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
395247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
395647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3959fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
396016ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
396347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
396647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
397147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3972dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
397447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
397973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
398047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
398347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
399347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
39990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
400247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
400447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
40100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
401347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
401472715f5c299a6482f8eb175070b056d77b74a43fcristy  if ((IssRGBColorspace(image->colorspace) != MagickFalse) &&
40153d627862fb79aad8a20be4f1587f0b8761db441aglennrp      ((image->gamma < .45) || (image->gamma > .46)) &&
40163d627862fb79aad8a20be4f1587f0b8761db441aglennrp           !(image->chromaticity.red_primary.x>0.6399f &&
40173d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
40183d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
40193d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
40203d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
40213d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
40223d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
40233d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
40243d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
40253d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
40263d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
40273d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
40283d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
40293d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
40303d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
40313d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f))
4032ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4033ccc36af759d30fb50b1deda241d038402a393b17glennrp       SetImageColorspace(image,RGBColorspace,exception);
4034ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
403572715f5c299a6482f8eb175070b056d77b74a43fcristy
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
4037ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4038ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4039ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
4040ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.width,(double) image->page.height,
4041ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.x,(double) image->page.y);
4042ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4043ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  image->colorspace: %d", (int) image->colorspace);
4044ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
404597f90e23c85b9c58387880125c29d8c99126f83aglennrp
404697f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
40480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41004383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
41014383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
41024383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
4103bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
412316ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4126bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413016ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
4138e0421fec74bee9a6f9def3d51aed4204f970ad73glennrp    reading_idat;
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4140bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
4154fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
41570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
415816ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
41660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
416716ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
41680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
41710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
4185151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      type[MagickPathExtent];
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
41980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
42010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
4203151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) ConcatenateMagickString(type,"errr",MagickPathExtent);
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4209e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
4210e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
42136af512ae5eeeed8effd9af4d57aab7caf74c65eddirk      ThrowReaderException(CorruptImageError,"CorruptImage");
42140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
421747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42188fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
42210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4225bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
42270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
423047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4237bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
4238e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[2] << 8) | p[3]);
4239bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
4240e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[6] << 8) | p[7]);
4241e2440c250d94d64f8c70e596fe90808795aaa07ecristy            if ((jng_width == 0) || (jng_height == 0))
4242e2440c250d94d64f8c70e596fe90808795aaa07ecristy              ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
424747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
425047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
425547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42592dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_width:      %16lu,    jng_height:     %16lu\n"
42602dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_color_type: %16d,     jng_image_sample_depth: %3d\n"
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
42622dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (unsigned long) jng_width, (unsigned long) jng_height,
42632dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_color_type, jng_image_sample_depth,
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
426547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42672dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_image_interlace_method:  %3d"
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
42692dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_image_interlace_method,
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
427147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42732dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_compression_method:%3d\n"
42742dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_filter_method:     %3d\n"
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
42762dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_compression_method,
42772dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_filter_method,
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
428147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42828fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
428447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
430073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
430147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
430447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
430616ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
43070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
43140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
43180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
432573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
43260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
433116ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
43320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
43430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
43470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
43500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
43590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
43620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
436503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
438247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
438947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43908fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
439247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
440147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4403889a928b732161b6353bd880e5ea0802f184c6d4glennrp        if (alpha_image != NULL && image_info->ping == MagickFalse)
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4409bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
441103812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44188fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
442647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4428889a928b732161b6353bd880e5ea0802f184c6d4glennrp        if (alpha_image != NULL && image_info->ping == MagickFalse)
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44378fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
44460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44478fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
44768182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
44770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
44878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
44888182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
44898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
44908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
44918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
44928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
44938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
449547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4504e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4505cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
4506da7803d6b1161960bc1e7db4d9718284c116fab8cristy            image->gamma=1.000f/2.200f;
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
451647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45255eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
45265eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
45270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
453447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45358fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
454516ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
454616ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
455016ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
455116ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4562fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
45638fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45708fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
45750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
459816ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
460447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
46080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4609f0eec7524321f1be1bfe568a13ab7d4d0333c814cristy  assert(color_image_info != (ImageInfo *) NULL);
4610151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) FormatLocaleString(color_image_info->filename,MagickPathExtent,"%s",
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
46120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
46150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
46260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
46290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4630bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
463216ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
463416ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
463516ea139d53d867211d3bb0fa859a83de653f687ecristy    {
463616ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
463716ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
463816ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
463916ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
464016ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
464116ea139d53d867211d3bb0fa859a83de653f687ecristy    }
464247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
46460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
46480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
465903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
46630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
46650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
466816ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4670151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(alpha_image_info->filename,MagickPathExtent,
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
46740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4676bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
467916ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
468147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
468217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy             if (image->alpha_trait != UndefinedPixelTrait)
468316ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
468416ea139d53d867211d3bb0fa859a83de653f687ecristy               {
468516ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
468616ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
468716ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
468816ea139d53d867211d3bb0fa859a83de653f687ecristy               }
46890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
469116ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
469316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
469416ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
46958a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->alpha_trait=BlendPixelTrait;
469616ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
469716ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
46990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
471147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
471247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
47200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
47220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
47230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
47260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
47280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
47320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
47390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
474044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp  if (status == MagickFalse)
474144c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp    return((Image *) NULL);
474244c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
47460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
47847ee973a2149db53911459cbf26f28eccdbc99efbglennrp    *image;
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
478721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
478821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
4795151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    magic_number[MagickPathExtent];
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4808fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
480916ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
48120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
48150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
481947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
482047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
482247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48233b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
482647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
482747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
482973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
48300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
48330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
483447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
483547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
48420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
485247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
48640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
4872151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    page_geometry[MagickPathExtent];
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
4875889a928b732161b6353bd880e5ea0802f184c6d4glennrp    *image;
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48774383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
487821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
487921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
48804383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4887bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
490516ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4912bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4918bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4935bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
494438ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
494538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
494638ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4947bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
496947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
497047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4976fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
497716ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
49800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
49830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
498747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
498847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
498947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
499073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
49910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
49940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
499547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
499647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
5004151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        magic_number[MagickPathExtent];
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
500647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
501047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
501147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5014bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
5015bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
501947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
5045151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      type[MagickPathExtent];
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
5056151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) ConcatenateMagickString(type,"errr",MagickPathExtent);
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5062e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
5063e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
506644c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp          {
506744c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp            status=MagickFalse;
506844c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp            break;
506944c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp          }
50700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
50730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
50760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50778fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
508047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
508347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5084bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
508647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
50960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
509816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
51000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
51070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
510916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
51110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
511647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
51210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51228fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
51280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5134bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
51360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5137bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
51390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5143e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5145e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
51498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
51500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
51530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
51570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
51600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
51648182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
51680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
51710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
51740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
517916ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
518147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
518216ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
51830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
51860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
51940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5195151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            (void) FormatLocaleString(page_geometry,MagickPathExtent,
5196e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
5197f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
51980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
5200bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
5202bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
52040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
52070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52188fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
52200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
52248182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
52250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
52280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5236280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  "    repeat=%d,  final_delay=%.20g,  iterations=%.20g",
5237280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  repeat,(double) final_delay, (double) image->iterations);
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
524616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
52510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
525316ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
5260edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  Instead of using a warning we should allocate a larger
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
526316ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
527216ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
52780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
52800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
52830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
52900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
52910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
52930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
52940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5298280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      "  x_off[%d]: %.20g,  y_off[%d]: %.20g",
5299280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->x_off[object_id],
5300280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->y_off[object_id]);
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
53100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
53170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
53400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
53430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
535516ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
536647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
536947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
537047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
53760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5377bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
538435ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
53930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53948fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
53990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
540347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5409bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
541612560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5424bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54278182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
54340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
544147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
544247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
54468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
54478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
54498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
54518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
54538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
54558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
54578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
546247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
546647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54728fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5474e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5475cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
548047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
548447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5487fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54928fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
549447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
549747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
550116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
55040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
55070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
551147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55128fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
55150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
55190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
552247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
552347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
552547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5526bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
552847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
553047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5531bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
554247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
55468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
55470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55488182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
55498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
55500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5551bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5552bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
55530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
55560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5561e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
556347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5566bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5567bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
55680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5569bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5570bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
55710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5572bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5573bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
55740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55753a89fa4ae8254eda5e264fb9d6bfd97ea3022773glennrp                        if (change_timeout == 2)
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
55770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5582e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
558447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
55900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5594e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5595e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
559647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
56040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5605bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
56070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5616e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5617e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
56180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
562247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
562316ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
562516ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
562647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
563347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
56380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
56480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
56568a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                image->alpha_trait=UndefinedPixelTrait;
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
565816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
56590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5663e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5664e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5670a454cdcb00e5a619edb3eac3070b649569448e4aglennrp
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
5680a454cdcb00e5a619edb3eac3070b649569448e4aglennrp            if (length > 3)
5681a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              {
5682a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                first_object=(p[0] << 8) | p[1];
5683a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                last_object=(p[2] << 8) | p[3];
5684a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                p+=4;
568547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5686a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                for (i=(int) first_object; i <= (int) last_object; i++)
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5688a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  if (mng_info->exists[i] && !mng_info->frozen[i])
5689a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    {
5690a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      MngBox
5691a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                        box;
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5693a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      box=mng_info->object_clip[i];
5694a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      if ((p-chunk) < (ssize_t) (length-17))
5695a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                        mng_info->object_clip[i]=
5696a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                           mng_read_box(box,(char) p[0],&p[1]);
5697a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    }
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
569947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5700a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              }
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5704a454cdcb00e5a619edb3eac3070b649569448e4aglennrp
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57178fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
572547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
572647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5738bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57458fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
575047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
575747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
575847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5759a454cdcb00e5a619edb3eac3070b649569448e4aglennrp            if (length > 3)
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5761a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              first_object=(p[0] << 8) | p[1];
5762a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              last_object=(p[2] << 8) | p[3];
5763a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              p+=4;
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5765a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
5766a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              {
5767a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                if (mng_info->exists[i] && !mng_info->frozen[i] &&
5768a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    (p-chunk) < (ssize_t) (length-8))
5769a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  {
5770a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    MngPair
5771a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      new_pair;
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5773a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    MngPair
5774a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      old_pair;
5775a454cdcb00e5a619edb3eac3070b649569448e4aglennrp
5776a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    old_pair.a=mng_info->x_off[i];
5777a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    old_pair.b=mng_info->y_off[i];
5778a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    new_pair=mng_read_pair(old_pair,(int) p[0],&p[1]);
5779a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    mng_info->x_off[i]=new_pair.a;
5780a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    mng_info->y_off[i]=new_pair.b;
5781a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  }
5782a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              }
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
578447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5791bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
579224e6d42307643613e0430bac65beddf8a43671bdglennrp            if (length > 4)
5793a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              {
5794a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                loop_level=chunk[0];
5795a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                mng_info->loop_active[loop_level]=1;  /* mark loop active */
579647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5797a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                /* Record starting point.  */
5798a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                loop_iters=mng_get_long(&chunk[1]);
57990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5800a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                if (logging != MagickFalse)
5801a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5802a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    "  LOOP level %.20g has %.20g iterations ",
5803a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    (double) loop_level, (double) loop_iters);
58040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5805a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                if (loop_iters == 0)
5806a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  skipping_loop=loop_level;
58070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5808a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                else
5809a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  {
5810a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    mng_info->loop_jump[loop_level]=TellBlob(image);
5811a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    mng_info->loop_count[loop_level]=loop_iters;
5812a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  }
58130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5814a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                mng_info->loop_iteration[loop_level]=0;
5815a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              }
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
581947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
582224e6d42307643613e0430bac65beddf8a43671bdglennrp            if (length > 0)
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
582424e6d42307643613e0430bac65beddf8a43671bdglennrp                loop_level=chunk[0];
582524e6d42307643613e0430bac65beddf8a43671bdglennrp
582624e6d42307643613e0430bac65beddf8a43671bdglennrp                if (skipping_loop > 0)
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
582824e6d42307643613e0430bac65beddf8a43671bdglennrp                    if (skipping_loop == loop_level)
582924e6d42307643613e0430bac65beddf8a43671bdglennrp                      {
583024e6d42307643613e0430bac65beddf8a43671bdglennrp                        /*
583124e6d42307643613e0430bac65beddf8a43671bdglennrp                          Found end of zero-iteration loop.
583224e6d42307643613e0430bac65beddf8a43671bdglennrp                        */
583324e6d42307643613e0430bac65beddf8a43671bdglennrp                        skipping_loop=(-1);
583424e6d42307643613e0430bac65beddf8a43671bdglennrp                        mng_info->loop_active[loop_level]=0;
583524e6d42307643613e0430bac65beddf8a43671bdglennrp                      }
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
583747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
583824e6d42307643613e0430bac65beddf8a43671bdglennrp                else
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
584024e6d42307643613e0430bac65beddf8a43671bdglennrp                    if (mng_info->loop_active[loop_level] == 1)
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
584224e6d42307643613e0430bac65beddf8a43671bdglennrp                        mng_info->loop_count[loop_level]--;
584324e6d42307643613e0430bac65beddf8a43671bdglennrp                        mng_info->loop_iteration[loop_level]++;
58440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
584524e6d42307643613e0430bac65beddf8a43671bdglennrp                        if (logging != MagickFalse)
584624e6d42307643613e0430bac65beddf8a43671bdglennrp                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
584724e6d42307643613e0430bac65beddf8a43671bdglennrp                          "  ENDL: LOOP level %.20g has %.20g remaining iters ",
584824e6d42307643613e0430bac65beddf8a43671bdglennrp                            (double) loop_level,(double)
584924e6d42307643613e0430bac65beddf8a43671bdglennrp                            mng_info->loop_count[loop_level]);
585047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
585124e6d42307643613e0430bac65beddf8a43671bdglennrp                        if (mng_info->loop_count[loop_level] != 0)
585224e6d42307643613e0430bac65beddf8a43671bdglennrp                          {
585324e6d42307643613e0430bac65beddf8a43671bdglennrp                            offset=
585424e6d42307643613e0430bac65beddf8a43671bdglennrp                              SeekBlob(image,mng_info->loop_jump[loop_level],
585524e6d42307643613e0430bac65beddf8a43671bdglennrp                              SEEK_SET);
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
585724e6d42307643613e0430bac65beddf8a43671bdglennrp                            if (offset < 0)
585824e6d42307643613e0430bac65beddf8a43671bdglennrp                              ThrowReaderException(CorruptImageError,
585924e6d42307643613e0430bac65beddf8a43671bdglennrp                                "ImproperImageHeader");
586024e6d42307643613e0430bac65beddf8a43671bdglennrp                          }
586124e6d42307643613e0430bac65beddf8a43671bdglennrp
586224e6d42307643613e0430bac65beddf8a43671bdglennrp                        else
586324e6d42307643613e0430bac65beddf8a43671bdglennrp                          {
586424e6d42307643613e0430bac65beddf8a43671bdglennrp                            short
586524e6d42307643613e0430bac65beddf8a43671bdglennrp                              last_level;
586624e6d42307643613e0430bac65beddf8a43671bdglennrp
586724e6d42307643613e0430bac65beddf8a43671bdglennrp                            /*
586824e6d42307643613e0430bac65beddf8a43671bdglennrp                              Finished loop.
586924e6d42307643613e0430bac65beddf8a43671bdglennrp                            */
587024e6d42307643613e0430bac65beddf8a43671bdglennrp                            mng_info->loop_active[loop_level]=0;
587124e6d42307643613e0430bac65beddf8a43671bdglennrp                            last_level=(-1);
587224e6d42307643613e0430bac65beddf8a43671bdglennrp                            for (i=0; i < loop_level; i++)
587324e6d42307643613e0430bac65beddf8a43671bdglennrp                              if (mng_info->loop_active[i] == 1)
587424e6d42307643613e0430bac65beddf8a43671bdglennrp                                last_level=(short) i;
587524e6d42307643613e0430bac65beddf8a43671bdglennrp                            loop_level=last_level;
587624e6d42307643613e0430bac65beddf8a43671bdglennrp                          }
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
588047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
588447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
588816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
589147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
589447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
59110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
59140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
59170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
592416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
592847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
593447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
594047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
594347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
594947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
595247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
595847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
596147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
596747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
597047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
597647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
597947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
598547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
598847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
599447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
599847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
600216ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
600647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
602547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
602916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
603247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
603547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
603916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
604247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
604547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
605047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
60668182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
60688182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
607247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
607916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
608147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
608747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
608916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
609247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
6095bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
6097bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
610547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
610847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
611147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
611447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
611747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
612047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
612347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
613147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
613447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
613747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
614247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
61508fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
615247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
615947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
616247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
616847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
617647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61778182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
61788182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
6191bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
6193bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
619516ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
620016ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
620147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
620847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
621247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
621947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
622247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
622347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
622447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
623316ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6236e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
6237e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
624816ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
625316ea139d53d867211d3bb0fa859a83de653f687ecristy              AcquireNextImage(image_info,image,exception);
625447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
626147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
62640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
62660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
627647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
62858a46d827a124555f0c48fb2368ec1bba8e079ab6cristy            image->alpha_trait=UndefinedPixelTrait;
628616ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
62870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6291e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6292e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
629647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
629716ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
630216ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
630347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
631047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
63160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
63190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
63280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
63370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
634347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
634747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
635247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6353bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
635447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
636547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6373889a928b732161b6353bd880e5ea0802f184c6d4glennrp        if (logging != MagickFalse)
6374889a928b732161b6353bd880e5ea0802f184c6d4glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6375889a928b732161b6353bd880e5ea0802f184c6d4glennrp            "exit ReadJNGImage() with error");
637647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
640947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
641247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
641447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
641547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
641747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64204e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
642147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
642447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
642747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
642947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
643047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
643247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
643647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
643947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
644147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
644247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
644447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64474e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
644847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
645147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
645447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
645647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
645747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
645947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
646916ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
647016ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
647116ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
647216ea139d53d867211d3bb0fa859a83de653f687ecristy
647316ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
647416ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
647516ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
647616ea139d53d867211d3bb0fa859a83de653f687ecristy
6477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
648116ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
648516ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
648616ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
648847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
648947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
649347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
649416ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
649547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65113faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6519bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
652347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6524bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
652616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
652716ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
652816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
652916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
653016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
653116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
653216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
653316ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
653416ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
653647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
654517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                if (image->alpha_trait != UndefinedPixelTrait)
654616ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
654747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
655016ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
655116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
655247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
655547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
655847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
656147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6570e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6571bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
65734f7c434c6c7047588b48a5b71281f9ecf4c9d1accristy                length=(size_t) GetPixelChannels(image)*image->columns;
657416ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
657516ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
657647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
657716ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
657816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
658547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
658847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6589bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6592bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
659347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6595bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
659647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6597bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6598bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
659947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6600bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
660247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
660547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
660947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6610bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
661647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
661916ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6622bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
66269fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
662716ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
662816ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
662947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6630bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6632fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6641bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
664216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
664316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
664416ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
664516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
664616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
664716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
664816ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
665047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6654bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
665516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
665616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
665716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
665816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
665916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
666016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
666116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
666216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6663bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
666447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
666816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
666916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
667016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6671bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
667216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
667316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
667416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
667516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6676bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
667716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
667816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
667916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
668016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6681bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
668216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
668347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
668417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                              if (image->alpha_trait != UndefinedPixelTrait)
668516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
668616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
668716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6688bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
668916ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
669147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
669616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
669716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
669916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
670016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
670347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6708bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
670916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
671016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
671116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
671216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
671316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
671416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
671516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
671616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6717bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
671847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6720bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
672116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
672216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
672316ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
672416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
672516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
672616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
672716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6728bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
672947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
673216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
673316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
673416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6735bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
673616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
673916ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
674016ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
674116ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
674347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
674647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
674947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
675016ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
675116ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6768e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
677216ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
677616ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
677716ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
677847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6779bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
678216ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
67837c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6785bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
678647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6787bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6788bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
678947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6790bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6791bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
679247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
679547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6797bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
679847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
680416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
680516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
680616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
680716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
680947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6813bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
681416ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
681516ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
681616ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
681716ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6818bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
681947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
682016ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
682416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
682516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
682616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6827bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
682816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6829bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
683016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
683116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
683216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6833bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
683416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6835bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
683616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
683716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
683816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6839bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
684016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
684117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                              if (image->alpha_trait != UndefinedPixelTrait)
684216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
684316ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
684416ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6845bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
684616ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
684847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6853bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
685416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
685516ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6856bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6858bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
685916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
686016ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6861bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
686447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6869bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
687016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
687116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
687216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
687316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6874bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
687547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6877bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
687816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
687916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
688016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
688116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6882bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
688347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
688716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
688816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
688916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6890bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
689116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
689416ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
689616ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
689847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69023faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6908bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
691147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6912bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
691416ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
691516ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
691616ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
691716ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
691816ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
691916ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
692016ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
692116ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
692216ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
692447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
695847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6974bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6975bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
698147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
699347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
700416ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70162b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
70172b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
701816ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
70192b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
70202b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
70212b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
70222b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
70232b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
70243faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7025cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
7026cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
7027cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
7028cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
7029cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
7030cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
703116ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
70328640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7034d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
7038bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7041d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
7045d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
704747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
704947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
705347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
70640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
706516ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
707016ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
707547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
707947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
70918a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
70920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
709416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
70950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
71000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
71030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
711147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
711216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
711547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
71200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
712547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
712616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
713147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
713947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
714016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
714447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
715047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
715116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
715347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
715647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
71640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
71670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
71700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
717547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
71810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
71830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7186e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
7187e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
71880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
719647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
719947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7201e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
720247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7207e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7219bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
722447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
722616ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
722747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
723047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
723347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
724247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
724547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
726247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
727247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
727547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7277e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
7278e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
727947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7281f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7282f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
728347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7284f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7285e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7286e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7287f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7288f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
728947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
729347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
729647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
729925c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
730447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
730747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
731047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
731525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7338bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7341bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
7344151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    version[MagickPathExtent];
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
735447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
736047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
736847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
7370151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) ConcatenateMagickString(version,"libpng ",MagickPathExtent);
7371151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MagickPathExtent);
737247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7375151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(version,",",MagickPathExtent);
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
7377151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            MagickPathExtent);
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
738047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
738106b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","MNG","Multiple-image Network Graphics");
738208e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags|=CoderSeekableStreamFlag;  /* To do: eliminate this. */
738347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
738847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
739047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
739347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7394afc97b1e31b78c973c4bf5e0be8d5090cfca8065glennrp  entry->mime_type=ConstantString("video/x-mng");
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
739806b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG","Portable Network Graphics");
739947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
740447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
740608e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7407d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
740847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
741147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
741506b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG8",
741606b627a07ff44e1ff93ef1288c9f428066ded10ddirk    "8-bit indexed with optional binary transparency");
741747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
742247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
742408e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7425d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
742806b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG24",
742906b627a07ff44e1ff93ef1288c9f428066ded10ddirk    "opaque or binary transparent 24-bit RGB");
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
743147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
7433151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) ConcatenateMagickString(version,"zlib ",MagickPathExtent);
7434151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MagickPathExtent);
743547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7438151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(version,",",MagickPathExtent);
7439151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(version,zlib_version,MagickPathExtent);
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
744247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
744547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
745047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
745208e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7453d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
745606b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG32","opaque or transparent 32-bit RGBA");
745747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
746247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
746408e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7465d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
746806b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG48",
746906b627a07ff44e1ff93ef1288c9f428066ded10ddirk    "opaque or binary transparent 48-bit RGB");
7470fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7471fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7472fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7473fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7474fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7475fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7476fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
747708e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7478d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7479fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7480fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
748106b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG64","opaque or transparent 64-bit RGBA");
7482fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7483fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7484fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7485fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7486fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7487fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7488fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
748908e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7490d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7491fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7492fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
749306b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG00",
7494c1e07709d63f88437cf56ddbc6b3889a96711346glennrp    "PNG inheriting bit-depth and color-type from original, if possible");
74955830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
74965830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
74975830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74985830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74995830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#endif
75005830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
75015830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
750208e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7503d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
75045830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) RegisterMagickInfo(entry);
75055830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
750606b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","JNG","JPEG Network Graphics");
750747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
75093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
75103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
751447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
751608e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
75177fee329aec1090ff832c1b07fc4cc70c3b604f65glennrp  entry->mime_type=ConstantString("image/x-jng");
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
752047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7521868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
75223d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy  ping_semaphore=AcquireSemaphoreInfo();
752318b17443128598500357da7bff2f01683cf32890cristy#endif
752447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
7554fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG48");
7555fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG64");
75565830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) UnregisterMagickInfo("PNG00");
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
755847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7559868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
7560cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
75613d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy    RelinquishSemaphoreInfo(&ping_semaphore);
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
756625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
758516ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
758616ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
759416ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7644cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
76720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
76730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
76750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7676ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7677a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
7678a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7679a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
7680a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
7684ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7685a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping,
7686a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy      (png_alloc_size_t) allocated_length);
7687a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
7688a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7689a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
7690a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
7691a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
7694151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      "Raw profile type ",MagickPathExtent);
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77033b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7704f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
770647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
77123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
771447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
772147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
772447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7730cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
77314383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
774547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
774647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
774747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
774947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7753cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
775547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
775647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
775747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
775847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
775947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
776047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7761cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7762cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7763cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
776447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
776547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
776647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
776747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
776847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
776947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
777047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7771cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
777247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
77733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
777447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
777747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7781fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
7782fd6fd07e58e3d37313bec849313ac6e2b92e3957dirkstatic void write_tIME_chunk(Image *image,png_struct *ping,png_info *info,
7783fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  const char *date,ExceptionInfo *exception)
7784fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk{
7785fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  unsigned int
7786fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    day,
7787fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    hour,
7788fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    minute,
7789fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    month,
7790fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    second,
7791fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    year;
7792fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7793fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_time
7794fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ptime;
7795fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7796fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  time_t
7797fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ttime;
7798fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7799fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (date != (const char *) NULL)
7800fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
7801fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      if (sscanf(date,"%d-%d-%dT%d:%d:%dZ",&year,&month,&day,&hour,&minute,
7802fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          &second) != 6)
7803fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
7804fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
7805fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            "Invalid date format specified for png:tIME","`%s'",
7806fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            image->filename);
7807fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          return;
7808fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
7809fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.year=(png_uint_16) year;
7810fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.month=(png_byte) month;
7811fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.day=(png_byte) day;
7812fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.hour=(png_byte) hour;
7813fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.minute=(png_byte) minute;
7814fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.second=(png_byte) second;
7815fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
7816fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  else
7817fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  {
7818fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    time(&ttime);
7819fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    png_convert_from_time_t(&ptime,ttime);
7820fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
7821fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_set_tIME(ping,info,&ptime);
7822fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk}
7823fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
7824b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7825b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
78263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
782716ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
78283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
78290997332e2c35a821b271d6e7473c01c10dc206adcristy  char
78300997332e2c35a821b271d6e7473c01c10dc206adcristy    im_vers[32],
78310997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_runv[32],
78320997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_vers[32],
78330997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_runv[32],
78340997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_vers[32];
78350997332e2c35a821b271d6e7473c01c10dc206adcristy
783616ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
783716ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
783816ea139d53d867211d3bb0fa859a83de653f687ecristy
783916ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
784016ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
784116ea139d53d867211d3bb0fa859a83de653f687ecristy
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
78433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
78443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
78463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
78473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
78493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
78523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7855cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7856cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7857e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7858e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
78595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
786039992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
786139992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
78623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
78645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
78655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
78665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
78673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
78745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
78755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
78765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7877bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
788158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
788221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
788358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
788458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7885da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7886fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7887d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
78888d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
788939992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7890991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7891918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_iCCP,
7892991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7893918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_sRGB,
7894991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
789526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
789626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
789726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7898a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7899e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
790026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
790126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
790226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
790326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
790426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
790526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
790626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7907fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_exclude_tIME,
7908e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
790926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
791026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
791126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
791226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
79138d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
7914ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_iCCP,
79150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
79160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
791782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
79188ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7919d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7920d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79220997332e2c35a821b271d6e7473c01c10dc206adcristy  MemoryInfo
7923af1534a4abd2d6ef7f7e2833b95400301faff3d3cristy    *volatile pixel_info;
79240997332e2c35a821b271d6e7473c01c10dc206adcristy
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
792816ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
792916ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
793016ea139d53d867211d3bb0fa859a83de653f687ecristy
7931bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
79360997332e2c35a821b271d6e7473c01c10dc206adcristy    *ping_pixels;
7937d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
79385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7939f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
79400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
79415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
79425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
79435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
79445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
79455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
79465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7947bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
79485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
79495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
79503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7951bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
79523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
79543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7956dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7957fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7958f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
79598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
79608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
79618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7962dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7963dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7964dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7965dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7966dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7967dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
79683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7969fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
79703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
797116ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
797216ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
797316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
797416ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7975b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7976d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
7977d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
7978d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
7979d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
7980d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
7981151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         MagickLibVersionText,MagickPathExtent);
7982d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
7983151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         MagickLibAddendum,MagickPathExtent);
7984ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7985d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
7986d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
7987ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
7988ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
7989ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
7990ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
7991ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7992d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
7993d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
7994ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
7995ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
7996ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
7997ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
7998ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
79998fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (logging != MagickFalse)
8000d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
8001d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    IM version     = %s",
8002d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           im_vers);
8003d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Libpng version = %s",
8004d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           libpng_vers);
8005ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(libpng_vers,libpng_runv) != 0)
8006ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8007ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8008ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           libpng_runv);
8009ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8010d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
8011d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           zlib_vers);
8012ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(zlib_vers,zlib_runv) != 0)
8013ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8014ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8015ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           zlib_runv);
8016ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8017d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
8018d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
80195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
80200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
80215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
80225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
80235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
80245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
80255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
80265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
80285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
80295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
80305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
80315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
80325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
80345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
80355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
80365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
80375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
8038dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
8039dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
8040dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
8041dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8042da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
8043f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp  ping_have_cheap_transparency=MagickFalse;
8044d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
80458d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
804639992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
8047991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
8048918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_iCCP=MagickFalse;
8049991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
8050918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_sRGB=MagickFalse;
8051991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
8052991d11dd9c33e65872778b81aff1347cd2878154glennrp
80530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
80540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
8055a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
8056dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
80570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
80580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
80590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
80600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
80610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
80620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
80630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
8064fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  ping_exclude_tIME=mng_info->ping_exclude_tIME;
8065dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
80660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
80670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
80680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
80690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
80708d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
8071ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  ping_preserve_iCCP = mng_info->ping_preserve_iCCP;
80720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
80730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
80740d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
80750d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
80760d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
80770d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
80780d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
8079ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8080ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * To do: recognize other variants of the sRGB profile, using the CRC to
8081ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * verify all recognized variants including the 7 already known.
8082ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8083ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Work around libpng16+ rejecting some "known invalid sRGB profiles".
8084ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8085ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Use something other than image->rendering_intent to record the fact
8086ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * that the sRGB profile was found.
8087ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8088ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Record the ICC version (currently v2 or v4) of the incoming sRGB ICC
8089ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * profile.  Record the Blackpoint Compensation, if any.
80900d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
8091ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   if (ping_exclude_sRGB == MagickFalse && ping_preserve_iCCP == MagickFalse)
80920d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
80930d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
80940d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
80950d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80960d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
80970d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
80980d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
80990d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
81000d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
81010d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
81020d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
81030d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81040d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
81050d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
81060d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
8107ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                (LocaleCompare(name,"ICM") == 0))
8108ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
8109ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             {
8110ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
8111ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
8112ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
81130d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81140d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8115ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
8116ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
8117ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
811829a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8119ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
8120ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
81210d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8122ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
812329a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8124ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
812529a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
8126ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
8127ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
8128ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
8129ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
8130ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8131ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
8132ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
81330d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8134ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
8135ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
81360d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8137ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8138ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
8139ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
8140ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
8141ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
8142ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
8143ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
8144ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8145ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
8146ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
8147ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
8148ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
8149ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
8150ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
8151ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
8152ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
8153ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
8154ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_iCCP = MagickTrue;
8155ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_zCCP = MagickTrue;
8156ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_have_sRGB = MagickTrue;
8157ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
8158ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
815929a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
81600d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
8161ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
816229a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8163ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
816429a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
816529a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
81660d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
81670d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
81680d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
81690d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
81700d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
81728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
81738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
81748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8175fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
8176fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8177fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
8178fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8179f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=UndefinedClass");
8180fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
8181fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8182f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=DirectClass");
8183fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
8184fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8185f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=PseudoClass");
8186f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(), image->taint ?
8187cc96f2d3d09f91c9333d05e2e7216d4006f8a5eaglennrp          "    image->taint=MagickTrue":
8188cc96f2d3d09f91c9333d05e2e7216d4006f8a5eaglennrp          "    image->taint=MagickFalse");
8189fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
819028af3713c9111a471cc868c787760de89236fa3cglennrp
8191750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  if (image->storage_class == PseudoClass &&
81927e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
8193fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png48 || mng_info->write_png64 ||
8194fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     (mng_info->write_png_colortype != 1 &&
8195fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png_colortype != 5)))
81967e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
819716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
81987e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
81997e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
82007e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
8201c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
820228af3713c9111a471cc868c787760de89236fa3cglennrp    {
8203c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
8204c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
8205c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
8206c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
8207c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8208c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
8209e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
8210c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
8211c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
821228af3713c9111a471cc868c787760de89236fa3cglennrp    }
8213bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8214c28acd632b7ea1724a54191d15db932f2e4d25e6glennrp  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
821516ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
82160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82173241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
82183241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
82193241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
82203241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
82213241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
822216ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
82233241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8224a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
8225a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
8226a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
8227a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
8228a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8229a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
8230a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8231a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
8232a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
8233a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
8234a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
82358e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
8236cd979955e4249aab3bdd79043718fa3b120239b8dirk  if (image->depth < 4)
823767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
823816ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
82398e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
82408e58efdecda887b08ef730d68290a61081ef2566glennrp
8241aac49630945ded4a68aca4f7c892e18b21afeba8dirk       if (image->depth > 2)
82428e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82438e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
824491d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
82458e58efdecda887b08ef730d68290a61081ef2566glennrp
82468e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82478e58efdecda887b08ef730d68290a61081ef2566glennrp           {
824816ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82498e58efdecda887b08ef730d68290a61081ef2566glennrp
825016ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82518e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82528e58efdecda887b08ef730d68290a61081ef2566glennrp
82538e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82548e58efdecda887b08ef730d68290a61081ef2566glennrp             {
825516ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
825616ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82578e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8258bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82598e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82608e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82618e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82628e58efdecda887b08ef730d68290a61081ef2566glennrp
82638e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82648e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82653e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82668e58efdecda887b08ef730d68290a61081ef2566glennrp             {
826791d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
82688e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82698e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82708e58efdecda887b08ef730d68290a61081ef2566glennrp         }
82718e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
82728e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82738e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
827491d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
82758e58efdecda887b08ef730d68290a61081ef2566glennrp
82768e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82778e58efdecda887b08ef730d68290a61081ef2566glennrp           {
827816ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82798e58efdecda887b08ef730d68290a61081ef2566glennrp
828016ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82818e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82828e58efdecda887b08ef730d68290a61081ef2566glennrp
82838e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82848e58efdecda887b08ef730d68290a61081ef2566glennrp             {
828516ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
828616ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82878e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8288bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82898e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82908e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82918e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82928e58efdecda887b08ef730d68290a61081ef2566glennrp
82938e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82948e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82953e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82968e58efdecda887b08ef730d68290a61081ef2566glennrp             {
829791d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
82988e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82998e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83008e58efdecda887b08ef730d68290a61081ef2566glennrp         }
83018e58efdecda887b08ef730d68290a61081ef2566glennrp       else
83028e58efdecda887b08ef730d68290a61081ef2566glennrp         {
83038e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
830491d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
83058e58efdecda887b08ef730d68290a61081ef2566glennrp
83068e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
83078e58efdecda887b08ef730d68290a61081ef2566glennrp           {
830816ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83098e58efdecda887b08ef730d68290a61081ef2566glennrp
831016ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
83118e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
83128e58efdecda887b08ef730d68290a61081ef2566glennrp
83138e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
83148e58efdecda887b08ef730d68290a61081ef2566glennrp             {
831516ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
831616ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
83178e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8318bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
83198e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
83208e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
83218e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83228e58efdecda887b08ef730d68290a61081ef2566glennrp
83238e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83248e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83253e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83268e58efdecda887b08ef730d68290a61081ef2566glennrp             {
832791d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
83288e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83298e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83308e58efdecda887b08ef730d68290a61081ef2566glennrp         }
8331cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
8332cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
833367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
833467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
833570e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
8336a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
83372b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
83382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
83392b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
83402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
83418e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
83422b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
83432b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
83442b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83453faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
8346cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
8347cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
8348cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
8349cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
8350cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
8351cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
8352c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
835316ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
83548640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
83558640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
83568640fb5e9b1094f35f8beab436f81661b8a99448glennrp
8357d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  image_colors = (int) image->colors;
8358d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_opaque = (int) image->colors;
8359d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_transparent = 0;
8360d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_semitransparent = 0;
8361d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
8362197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  if (mng_info->write_png_colortype &&
8363a8036d6466b63ead629795b60772f160cca77c4cglennrp     (mng_info->write_png_colortype > 4 || (mng_info->write_png_depth >= 8 &&
8364a8036d6466b63ead629795b60772f160cca77c4cglennrp     mng_info->write_png_colortype < 4 &&
836517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     image->alpha_trait == UndefinedPixelTrait)))
8366a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8367a8036d6466b63ead629795b60772f160cca77c4cglennrp     /* Avoid the expensive BUILD_PALETTE operation if we're sure that we
8368a8036d6466b63ead629795b60772f160cca77c4cglennrp      * are not going to need the result.
8369a8036d6466b63ead629795b60772f160cca77c4cglennrp      */
8370a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (mng_info->write_png_colortype == 1 ||
8371a8036d6466b63ead629795b60772f160cca77c4cglennrp        mng_info->write_png_colortype == 5)
8372a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickFalse;
8373a8036d6466b63ead629795b60772f160cca77c4cglennrp
837417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     if (image->alpha_trait != UndefinedPixelTrait)
8375a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8376a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 2;
8377a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 1;
8378a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8379a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
8380a8036d6466b63ead629795b60772f160cca77c4cglennrp
8381a3a520c28bd76680b547f37a391bd8f441b49fbfglennrp  if (mng_info->write_png_colortype > 1 && mng_info->write_png_colortype < 7)
8382a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8383a8036d6466b63ead629795b60772f160cca77c4cglennrp  /* BUILD_PALETTE
8384a8036d6466b63ead629795b60772f160cca77c4cglennrp   *
8385a8036d6466b63ead629795b60772f160cca77c4cglennrp   * Normally we run this just once, but in the case of writing PNG8
8386e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
8387e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
83888ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
83898ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
83908ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
83918ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
8392c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
839382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
83948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
839582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
8396d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
839782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
83988ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
8399d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
8400a8036d6466b63ead629795b60772f160cca77c4cglennrp    /*
8401d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
8402d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
8403d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
8405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
8406d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
8407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8408d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
84108a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     * If image->alpha_trait is MagickFalse, we ignore the alpha channel
8411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8415d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8416d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
84203c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
84238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
842416ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
84288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
842916ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
843016ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8431d6bf1617e99df0272b231855a933a74e99b6578fglennrp
843216ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
843316ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8434fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8435fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8439d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8441d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8443d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84478a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             "      image->alpha_trait=%.20g",(double) image->alpha_trait);
844803812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
84503c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8451fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
84527ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
84537ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8454d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
84558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
845616ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
84572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
84597ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
846616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
84677ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
84682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8473d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8474d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8478d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
847916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
84832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
848683c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
848816ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
848916ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
84907ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
84918d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
84928d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84938d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
84957ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8497fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8498fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8499fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
85002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8502d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
85047ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
850516ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8506d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
850797fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
851017f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy           if (image->alpha_trait == UndefinedPixelTrait ||
851116ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
85128d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8513d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
85148d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8515d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8516d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
851716ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
851816ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8519d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8520d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8521d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8522d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8523d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
852416ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, opaque+i))
8525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8527d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
852816ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8530d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
853116ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
853216ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85348d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85358d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
853616ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
85378d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8538d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
85398d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8540d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8541d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
854216ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
854316ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
854416ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
854516ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
854616ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
854716ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
854816ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
854916ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
8550972d1c4895c4ee6da1b6745e1bb9cb71ee5d6d08cristy                         GetPixelGray(image,q);
8551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8552d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8554d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8555d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
855616ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, transparent+i))
8557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8558d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8561d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8562d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
856416ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8565d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85668d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85678d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8568d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8569d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8570d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8571d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8572d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8573d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
857416ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8576d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85778d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8578d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8579d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
858016ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
858116ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
858216ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8583d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8585d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8586d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8587d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8588d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8589d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
859016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8592d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
85938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
859416ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8595d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8596d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
85973c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
85984054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
85994054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8600d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8601d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8602d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8603d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8604c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8605c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8606c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8607c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8608c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8609c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8610c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8611c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8612d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8613d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8614ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8615ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8616ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8617ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8618d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8619d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
862003812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
86218e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8622c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8623388a8c871db8f82488f34c4f41fc64a58b8cfbf7glennrp               number_opaque++;
8624c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8625c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8626c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8627c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8628c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8629c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
863003812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8631a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8632a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8633a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8634d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8636d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
86373241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8638d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8639d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8640d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8641d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8642d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
86433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8644d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8645d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8646d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8647d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86483241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
86498d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
86508d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
86518d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8652fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8653d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8654d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
86550fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         ping_have_non_bw=MagickFalse;
86560fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
865745d4c34ce93ff377b9671844ffa1153b821061f6glennrp         if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
86580fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
865996bc620815234aaec28b928df51d1754cbe390dcglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
866096bc620815234aaec28b928df51d1754cbe390dcglennrp              "incompatible colorspace");
86617fb2652ba366fc984d1dbb0c66560b91c57dab78cristy           ping_have_color=MagickTrue;
866298b95773e388844e22c6e4006bb88396b33cf6b4glennrp           ping_have_non_bw=MagickTrue;
86630fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
86640fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
8665d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8666d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8667d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8668d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8669d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
86706185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
867116ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8672d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
86736185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8674e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8675e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8676e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
867716ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
867816ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8679e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8680e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8681e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8682e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8683e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
868416ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8685e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8686e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8687e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8688e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8689e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8690d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8691d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8692d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
86936185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8694d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8695d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8696d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8697d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
86986185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
869916ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
870016ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8701d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8702d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8703e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8704d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
870516ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8706d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8707e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8708d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8709bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8710bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
87114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8712d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8713d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
871416ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8715d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8716bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8717d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8718d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8719d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8720d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8721d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8722d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8723d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8724d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8725d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8726d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8727d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
87283241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8729d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8730d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
87313241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8732d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8733d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8734d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8735d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8736d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8737d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8738c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8739c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8740bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8741d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8742d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8743d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8744d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8745d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8746d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8747d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8748d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8749d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8750d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8751d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8752d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8753d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8754d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8755d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8756d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8757d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8758d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8759d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8760d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8761d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8762d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
87633241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8764d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8765d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8766d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8767d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8768d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8769d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8770d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
87716185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8772d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8773d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8774d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8775d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
87762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8777d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8778d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8779d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8780d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8781d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8782d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
878316ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8784d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
87853faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
87863faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8787d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8788d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8789d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8790d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8791d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8792d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8793d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8794d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8795d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8796bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8797d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8798d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8799d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8800d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8801fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8802fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8803d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8804d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
880516ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
88063c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
880716ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8808d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
88093c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8810d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8811d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8812d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
881303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
881417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                  if ((image->alpha_trait == UndefinedPixelTrait ||
881516ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
881616ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
881716ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
881816ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
88196185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
882016ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8821d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
88226185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
882303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
882416ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8825d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8826d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8827d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8828d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8829d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8830d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8831d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8832d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8833d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8834d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8835d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8836d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8837d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8838d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8839d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8840d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
884116ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
884283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8843d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8844d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
884572988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8846d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8847d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8848d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8849d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8850d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8851d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8852d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
885316ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8854d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
88556185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
88566185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
88573c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8858d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8859d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8860d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8861d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8862d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
88633c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8864d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8865d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
88663c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8867d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8868d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8869d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8870d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
887103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8872d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8873d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8874d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
88756185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8876d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8877d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8878d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8879d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
88806185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8881d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8882d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8883d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8884a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8885d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8886d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8887d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8888a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8889d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8890d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8891d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8892d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8893d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8894d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8895d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
88966185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
889703812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
889803812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8899d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
89003c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8901c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8902c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8903fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8904c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8905c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8906c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8907c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8908c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8909c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8910fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8911c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8912130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8913130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8914130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8915c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8916130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8917c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8918c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8919c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8920fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8921c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8922c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
892316ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8924fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
892516ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8926c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8927fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8928c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8929c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
893016ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
89318ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
893211a06d3f2cac0f17af7963e83bc6e9ebd2a377c0cristy                  SetPixelViaPixelInfo(image,&image->background_color,r);
893316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
89348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
89358ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
893616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
893716ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8938c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8939bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8940c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8941c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8942fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8943c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8944c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8945c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
894616ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
894716ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
894816ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
8949c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8950c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8951c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8952c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8953c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8954e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8955e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8956e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8957c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8958d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8959d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8960d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8961d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8962d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8963d337164012450d70d62e71cf4a308a29004f7d57glennrp
8964d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8965d337164012450d70d62e71cf4a308a29004f7d57glennrp
896691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8967d337164012450d70d62e71cf4a308a29004f7d57glennrp
8968d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8969d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8970d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8971d337164012450d70d62e71cf4a308a29004f7d57glennrp
8972d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8973d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8974d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8975d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
897616ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8977d337164012450d70d62e71cf4a308a29004f7d57glennrp
897816ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8979d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
8980d337164012450d70d62e71cf4a308a29004f7d57glennrp
8981d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
8982d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
898316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
898454cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
898516ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8986d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
8987bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8988d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8989d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
8990d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8991d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8992d337164012450d70d62e71cf4a308a29004f7d57glennrp
8993d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
8994d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
8995d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8996d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
8997d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8998d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
89998e58efdecda887b08ef730d68290a61081ef2566glennrp
9000d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
9001d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
900291d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
9003d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
9004d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9005d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
9006d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
9007d337164012450d70d62e71cf4a308a29004f7d57glennrp
900882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
900982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
901082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
901182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
901282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
901382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
901482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
901582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
901691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
901782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
901882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
901982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9020e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
902182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
902282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
902382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
902482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
902582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
902616ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
902782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
902816ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
902982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
903082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
903182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
903282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
903316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
903416ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
903516ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
903682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
9037bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
903882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
903982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
904082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
904182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
904282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
904382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
904482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
904582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
904682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
904782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9048e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
904982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
905082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
905191d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
905282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
9053d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9054d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
905582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
9056c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
9058c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
9059c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9060c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9061c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
9062c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90638ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
90648ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
90653faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
90663faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
90673faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
90683faa9a3fb01696daaf976d595f492cb530bffb21glennrp
906991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
9070fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9071c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9072c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9073e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
9074fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9075c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
9076c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9077c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
9078c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
907916ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
90808d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
908116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
9082c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
9083c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
9084c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
9085c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
908616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
908754cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
908816ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
9089c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
9090bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9091c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
9092c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
9093c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9094c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
9095c722dd852e8abe407c2846d39662f7ade9c234deglennrp
9096c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
9097c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
9098c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9099c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
9100c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9101e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
9102c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
9103c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
910491d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
9105c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9106c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
9107c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
9108c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
91098ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91108ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
91118ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
911234ef720923a27004960cbcf4d75a8075445e85d7glennrp      /* Take care of special case with 256 opaque colors + 1 transparent
91138ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
91148ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
91158ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
91168ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
911734ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
911834ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
911934ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red background colors to 3-3-2-1");
912034ef720923a27004960cbcf4d75a8075445e85d7glennrp
91218ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
91228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
91238ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
91248ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91258ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
91268ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
9127bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
912834ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
912934ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
913034ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red pixel colors to 3-3-2-1");
913134ef720923a27004960cbcf4d75a8075445e85d7glennrp
91328ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
91338ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
91358ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
913616ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
9137bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
913816ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
91398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
9140bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91418ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
91428ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
914316ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
914416ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
914516ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
914616ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
91478ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
914816ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
91498ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
915016ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
91518ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
9152bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91538ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
91548ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
9155bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91568ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
91578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91588ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91598ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
91608ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91618ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
91628ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
91638ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
91648ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
91658ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
91668ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
91678ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
91688ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
91698ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
91708ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91718ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
9172fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
9173a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
9174fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
9175fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9176fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
9177fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
9178fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
9179fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
91800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
91810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
91820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
9183d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
91840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
91860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
91870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
91890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
91900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91918d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
9192d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
91930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
91940b206f5daa453dc1035db5890cabc899736dc2d0glennrp
91950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
91960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
9197fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
9198fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
9199fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
92005a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
92015a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
92025a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
9203fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
92045a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
92055a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
9206fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
9207fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
9208fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9209fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
9210fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
9211fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9212fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
9213fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
9214fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
921516ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
9216fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
9217fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9218fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
9219fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
9220fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
9221fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
922216ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
9223fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
9224fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9225fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
9226fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
922716ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
922816ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
922916ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
923016ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
923116ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
923216ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
923316ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
9234fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
9235fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
9236fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
9237fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
9238fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
923916ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
9240fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
9241bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9242fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
9243fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
9244fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
9245fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9246fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
9247fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
924867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
924967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
925067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
9251fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
925267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
925367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
925467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
925567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
9256fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
925767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
925867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
9259fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
9260fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9261bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9262fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
9263fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
9264fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
9265fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9266fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
9267fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9268fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
9269fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9270fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
9271fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9272fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
9273fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
9274fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
9275fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
92763c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
92773c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
92783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
92793c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
9280f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
928117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  image_matte=image->alpha_trait != UndefinedPixelTrait ? MagickTrue : MagickFalse;
928283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
928348c20621d4ce02a3833b107f710843d1e524d559glennrp  if (mng_info->write_png_colortype < 5)
9284197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette=image->storage_class == PseudoClass &&
9285197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      image_colors <= 256 && image->colormap != NULL;
9286197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  else
9287197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette = MagickFalse;
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
928952a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
929052a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
929152a479ca718756af72f96e127f8256499ab68f76glennrp    {
929216ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
929316ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
929416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
929515e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
929616ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
929752a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
929852a479ca718756af72f96e127f8256499ab68f76glennrp    }
929952a479ca718756af72f96e127f8256499ab68f76glennrp
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
930416ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
930516ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
93063e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
9307cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
9308cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
93090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
93113e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
9312cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
93130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
93190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
93270997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=(MemoryInfo *) NULL;
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
9339868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9340cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9342edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
93430997332e2c35a821b271d6e7473c01c10dc206adcristy      if (pixel_info != (MemoryInfo *) NULL)
93440997332e2c35a821b271d6e7473c01c10dc206adcristy        pixel_info=RelinquishVirtualMemory(pixel_info);
9345edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9346edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (quantum_info != (QuantumInfo *) NULL)
9347edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        quantum_info=DestroyQuantumInfo(quantum_info);
9348edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
934916ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
935016ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
935116ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
935216ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9355edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9356edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
9357edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
9358edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
9359edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
9360edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9361868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9362edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
9363edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
9364edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9365943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
9366a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
9367a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
9368a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
9369a3a5f956194e91458e2789966ad15308e8f3df47glennrp
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93739bf97b6c2143eb20c330346b01e82102cc082725glennrp
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
937625024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  {
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
937825024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
937925024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     /* Disable new libpng-1.5.10 feature when writing a MNG because
938025024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      * zero-length PLTE is OK
938125024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      */
938225024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     png_set_check_for_invalid_index (ping, 0);
938325024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# endif
938425024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  }
93852b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
93902b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93932b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
93952b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93964e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
93974e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
93982b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9402fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48 || mng_info->write_png64)
9403fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     image_depth=16;
9404fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
94070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
94110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
94170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9421e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9423e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94258a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        "    image_matte=%.20g",(double) image->alpha_trait);
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94278640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94298640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94318640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
94335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
9434dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
943526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
943726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
943826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
943916ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
9443dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9444dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9448dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
9449823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
945016ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
9451823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
945216ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9454dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9457dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
945816ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
945916ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9461991d11dd9c33e65872778b81aff1347cd2878154glennrp
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9464dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
946516ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
946616ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9468991d11dd9c33e65872778b81aff1347cd2878154glennrp
9469823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9470823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9471823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9472823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9473823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9474991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
947626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9478a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
947926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
948026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9481a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9483a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9484a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9485a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9486a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9487a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9488a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
94890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9490a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9491a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
94920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9493a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9494a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
94950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9496a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9497a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
94980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9499a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9500a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
95010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9502a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9503a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
95040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9505a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9506a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9507c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9508c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
95090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
95100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
95123b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
95133b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95143b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9515c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9516c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9517c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
95183b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
95193b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95203b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
95213b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
95220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
952426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
95253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
95310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95321273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
95333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9534fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
95350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
95360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
95388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
95398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
95400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
95420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
95430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
95440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
95450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
95470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9549f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
95500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
95520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
95530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
95540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
95550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
95560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
95570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
955867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
95590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
956067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
956167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
956267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
95630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
95643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
95662b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
95688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
95698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
95705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
957158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
95728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
95730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
95740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
95750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
95760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
95778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
95783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
95808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
95810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95832cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
95848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
95850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
95870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
95880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
95908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
95918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
95920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95931273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
95944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
95951273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
95961273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
95971273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
95981273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
95994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
96004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
96014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
96020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9604c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9605c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9606c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9607c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9608c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9609c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9610c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
96114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
96123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
96130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9614fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png_colortype == 1)
9615fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
9616fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image_matte=MagickFalse;
9617fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
9618fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
9619fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
9620fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png24 || mng_info->write_png48 ||
9621fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 3)
96223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
96245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9627fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png32 || mng_info->write_png64 ||
9628fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 7)
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
96315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
96370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
96393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
96410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
96435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
96452cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
96487c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
96497c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
96507c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96517c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96547c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96583c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
96590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9660d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
96618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
96620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9663d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
96673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9669def23e5d7331b1a13ed593b6d6aca516da382328cristy          if (image_info->type == TrueColorAlphaType)
96703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
96733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
9676def23e5d7331b1a13ed593b6d6aca516da382328cristy              image_info->type == PaletteAlphaType)
96775aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
96785aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
96797c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
9680261f64eea2c3a5a9586da65af2c59d2a39b05de0glennrp             image_info->type == UndefinedType)
96813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96825aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
96838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
96845aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
96855aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96865aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
96875aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
96885aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96900b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
96915aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96925aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
96935aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
96945aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
96965aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
96975aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
96985aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
96995aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97005aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
97015aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
97025aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
97040b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
97055aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97065aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
97075aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
97085aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97095aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
97100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
97115aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
97123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
971526c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97168640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
971726c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
97185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
97190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
97200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
97210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
97220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
97230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
97240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9726d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9727d6bf1617e99df0272b231855a933a74e99b6578fglennrp
97285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
97293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
973017f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy          if (image->alpha_trait == UndefinedPixelTrait && ping_have_non_bw == MagickFalse)
97318d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97338640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
973635ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
97375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
97380f111984738842d27d04aed2a3f823d82a943506glennrp
97390f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
97400f111984738842d27d04aed2a3f823d82a943506glennrp           {
97410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9742edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"image has 0 colors");
97430f111984738842d27d04aed2a3f823d82a943506glennrp           }
97440f111984738842d27d04aed2a3f823d82a943506glennrp
974535ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
97465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9747d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
97483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9749d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9750d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9751d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9752d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
97530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9754d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9755d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9756d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
97570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9758d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9759d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
97603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
97632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97671a56e9c9268976936eeab9fe97eb664b847e444cglennrp        "    Tentative PNG color type: %s (%.20g)",
97681a56e9c9268976936eeab9fe97eb664b847e444cglennrp        PngColorTypeToString(ping_color_type),
97691a56e9c9268976936eeab9fe97eb664b847e444cglennrp        (double) ping_color_type);
97700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9772e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
97730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9775e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
97760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
97798640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
97808640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97818640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9782e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
978558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
97863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
97884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
97897c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
97907c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
97917c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
97922b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97937c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
97947c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
97957c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
97962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
97984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
97993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
98014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
98034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
98044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9805a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
98064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
98077c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
98087c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98097c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
98104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
98134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9815bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
98180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
98204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
98210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
98234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
98240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
98264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
98270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
98294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
98300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
98324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
98330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
98354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
98360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
98384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
98390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
984111a06d3f2cac0f17af7963e83bc6e9ebd2a377c0cristy                (ScaleQuantumToShort(GetPixelInfoIntensity(image,
98424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
98430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
98450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
98474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9852fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9853fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9854fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9855fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9856fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
98574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98582b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98617c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98627c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
98630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
98654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
98664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
98674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
98684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
98694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
98704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
98714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
98734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
98744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
98753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
98763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
98775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
98785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
98795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
98805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98848640fb5e9b1094f35f8beab436f81661b8a99448glennrp
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
98860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98872e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
98890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
989039992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
98928d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
98938d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
989535ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
98960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
98989c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
98990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99007c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
99034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
99054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
99064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
99074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
99084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
99104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
99114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
99124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
99170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9918136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9919d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9920f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
99210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
99235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
99240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
99285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
99325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
99330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
993435ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9935bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
99365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
99373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99392b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
99410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
99451a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9951bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
99553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
99613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
99624bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
99633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
99652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
99679c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
99680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
99709c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
99710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
99739c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99762b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
99790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
99810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
998417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
998517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
99915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
99920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99933d627862fb79aad8a20be4f1587f0b8761db441aglennrp            if (!(mng_info->have_write_global_plte && matte == MagickFalse))
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9995bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
99963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
99993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
100010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100023b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
100033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1000498156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
10005f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
100060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1000739992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
100083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
10011d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
100123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10013befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
10014befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
10015befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
100165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
10017befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
100180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1001916ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
100205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
100240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1002558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
100260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
100270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
10028d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
10029d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
100300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10032d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
10033d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
100343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
100360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
100370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10038d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
100390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
10040c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
10041c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
10042c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10043c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
10044c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
10045d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
10046d6bf1617e99df0272b231855a933a74e99b6578fglennrp
10047d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
10048d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
10049750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp                       ping_trans_alpha[i]= (png_byte)
1005016ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
10051d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
100520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
100530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10059c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
100620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
100654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
100694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
100755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
100765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
100775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
100784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
100834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100904383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
100914383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
100922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
100943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
100953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
100965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
100983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
101013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1010235ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
1010335ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
1010435ef824baa82511126ff0072ae30eee0da9c05a3cristy
1010522ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
101063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
1010826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
101093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1011016ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
1011111a06d3f2cac0f17af7963e83bc6e9ebd2a377c0cristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(image,
1011216ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
1011316ea139d53d867211d3bb0fa859a83de653f687ecristy
101143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
101158f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1011616ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
1011716ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1011816ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
1011916ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
101203b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
10121991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
1012226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101243e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101253e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101263e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
101273e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
101283e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101299be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
101303e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
101313e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101323e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101333e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101343e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
101353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1013617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1013726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1013826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
101391273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
1014017a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
1014117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
1014217a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
1014317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
1014417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1014517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
1014617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10147a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
10148a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
1014917a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
1015017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1015117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
1015217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101533b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
101540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
101550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
101570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
10158a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1015913d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
10160a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
101610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
101623b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
101633b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
101650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
101670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
101680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
101690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
101700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
10171a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
1017217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10173d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
101743c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
101753b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101763b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101773b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
101783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
101793c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
1018017a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
1018126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1018217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101851a56e9c9268976936eeab9fe97eb664b847e444cglennrp      "    PNG color type: %s (%d)", PngColorTypeToString(ping_color_type),
101861a56e9c9268976936eeab9fe97eb664b847e444cglennrp      ping_color_type);
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
101883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
101893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
101920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
101940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
101970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
101980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
102000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
102040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102054054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
102064054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
1020710d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
1020810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1020910d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
1021010d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
1021110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1021210d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
1021310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10214ef804f5802b3d6517d516556b64fccc5843710b6glennrp        0 or omitted: Use Z_HUFFMAN_ONLY strategy with the
1021510d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
1021610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1021710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
1021810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1021910d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
1022010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022110d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
1022210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
1022410d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
1022510d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
10226750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
1022710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
1022810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022910d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
1023085dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             a MNG, otherwise "none".  Did not work in IM-6.7.0-9
1023110d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
1023210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1023385dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp        8:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), adaptive
1023485dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             filtering. Unused prior to IM-6.7.0-10, was same as 6
1023510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10236ef804f5802b3d6517d516556b64fccc5843710b6glennrp        9:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), no PNG filters
102371868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
1023810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1023910d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
1024010d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
1024116ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
1024216ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
1024310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1024410d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
1024510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1024629dd80efe8d7489d5f689a8a723454e684f92a8fdirk  quality=image_info->quality == UndefinedCompressionQuality ? 75UL :
1024729dd80efe8d7489d5f689a8a723454e684f92a8fdirk     image_info->quality;
102480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102491868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
102501868258559ddf946fa73ef72dd43507b32623705glennrp    {
102511868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
102521868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
102531868258559ddf946fa73ef72dd43507b32623705glennrp    }
10254750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
102551868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
102563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
102583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
102593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10260bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
102610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102621868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
102631868258559ddf946fa73ef72dd43507b32623705glennrp    }
102640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102651868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
102661868258559ddf946fa73ef72dd43507b32623705glennrp    {
102671868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
10268a24b245fac14ef0617d691de0942697f2eb31b05glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
10269a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy=Z_RLE+1;
10270a24b245fac14ef0617d691de0942697f2eb31b05glennrp#else
10271a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
10272a24b245fac14ef0617d691de0942697f2eb31b05glennrp#endif
102733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102751868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
102761868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
102771868258559ddf946fa73ef72dd43507b32623705glennrp
102781868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102801868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
102813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102821868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
102831868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
102840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102851868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
102861868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102871868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
102881868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
102890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102901868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102911868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
102923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102934054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
1029410d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102951868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
102964054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
102974054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
102981868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102991868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
103001868258559ddf946fa73ef72dd43507b32623705glennrp        else
103011868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103021868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
103031868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
103043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103061868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
103071868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
103080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103091868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
103101868258559ddf946fa73ef72dd43507b32623705glennrp    {
103111868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
103121868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
103131868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
103141868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103151868258559ddf946fa73ef72dd43507b32623705glennrp      else
103161868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
103171868258559ddf946fa73ef72dd43507b32623705glennrp     }
103184054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
103191868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
103201868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
1032110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
103221868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
103231868258559ddf946fa73ef72dd43507b32623705glennrp    {
103241868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
103251868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
103261868258559ddf946fa73ef72dd43507b32623705glennrp      {
103271868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
103281868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
103291868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
103301868258559ddf946fa73ef72dd43507b32623705glennrp      }
103311868258559ddf946fa73ef72dd43507b32623705glennrp#endif
103324054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103331868258559ddf946fa73ef72dd43507b32623705glennrp    }
103340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103351868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
103361868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103381868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
103391868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
103401868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
103410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103421868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
103431868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
103441868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
103452b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10346dec72c9b492c176af9813be3105518e91835ed37glennrp  ping_interlace_method=image_info->interlace != NoInterlace;
10347dec72c9b492c176af9813be3105518e91835ed37glennrp
10348dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_mng)
10349dec72c9b492c176af9813be3105518e91835ed37glennrp    png_set_sig_bytes(ping,8);
10350dec72c9b492c176af9813be3105518e91835ed37glennrp
10351dec72c9b492c176af9813be3105518e91835ed37glennrp  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
10352dec72c9b492c176af9813be3105518e91835ed37glennrp
10353dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_png_colortype != 0)
10354dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10355dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
10356dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10357dec72c9b492c176af9813be3105518e91835ed37glennrp         {
10358dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
10359dec72c9b492c176af9813be3105518e91835ed37glennrp
10360dec72c9b492c176af9813be3105518e91835ed37glennrp           if (ping_bit_depth < 8)
10361dec72c9b492c176af9813be3105518e91835ed37glennrp             ping_bit_depth=8;
10362dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10363dec72c9b492c176af9813be3105518e91835ed37glennrp
10364dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
10365dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10366dec72c9b492c176af9813be3105518e91835ed37glennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
10367dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10368dec72c9b492c176af9813be3105518e91835ed37glennrp
10369dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_need_colortype_warning != MagickFalse ||
10370dec72c9b492c176af9813be3105518e91835ed37glennrp     ((mng_info->write_png_depth &&
10371dec72c9b492c176af9813be3105518e91835ed37glennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
10372dec72c9b492c176af9813be3105518e91835ed37glennrp     (mng_info->write_png_colortype &&
10373dec72c9b492c176af9813be3105518e91835ed37glennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10374dec72c9b492c176af9813be3105518e91835ed37glennrp      mng_info->write_png_colortype != 7 &&
10375dec72c9b492c176af9813be3105518e91835ed37glennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
10376dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10377dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10378dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10379dec72c9b492c176af9813be3105518e91835ed37glennrp          if (ping_need_colortype_warning != MagickFalse)
10380dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10381dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10382dec72c9b492c176af9813be3105518e91835ed37glennrp                 "  Image has transparency but tRNS chunk was excluded");
10383dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10384dec72c9b492c176af9813be3105518e91835ed37glennrp
10385dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_depth)
10386dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10387dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10388dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:bit-depth=%u, Computed depth=%u",
10389dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_depth,
10390dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_bit_depth);
10391dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10392dec72c9b492c176af9813be3105518e91835ed37glennrp
10393dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_colortype)
10394dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10395dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10396dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:color-type=%u, Computed color type=%u",
10397dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_colortype-1,
10398dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_color_type);
10399dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10400dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10401dec72c9b492c176af9813be3105518e91835ed37glennrp
10402dec72c9b492c176af9813be3105518e91835ed37glennrp      png_warning(ping,
10403dec72c9b492c176af9813be3105518e91835ed37glennrp        "Cannot write image with defined png:bit-depth or png:color-type.");
10404dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10405dec72c9b492c176af9813be3105518e91835ed37glennrp
1040617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  if (image_matte != MagickFalse && image->alpha_trait == UndefinedPixelTrait)
10407dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10408dec72c9b492c176af9813be3105518e91835ed37glennrp      /* Add an opaque matte channel */
10409dec72c9b492c176af9813be3105518e91835ed37glennrp      image->alpha_trait = BlendPixelTrait;
10410dec72c9b492c176af9813be3105518e91835ed37glennrp      (void) SetImageAlpha(image,OpaqueAlpha,exception);
10411dec72c9b492c176af9813be3105518e91835ed37glennrp
10412dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10413dec72c9b492c176af9813be3105518e91835ed37glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10414dec72c9b492c176af9813be3105518e91835ed37glennrp          "  Added an opaque matte channel");
10415dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10416dec72c9b492c176af9813be3105518e91835ed37glennrp
10417dec72c9b492c176af9813be3105518e91835ed37glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10418dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10419dec72c9b492c176af9813be3105518e91835ed37glennrp      if (ping_color_type < 4)
10420dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10421dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_have_tRNS=MagickTrue;
10422dec72c9b492c176af9813be3105518e91835ed37glennrp           if (logging != MagickFalse)
10423dec72c9b492c176af9813be3105518e91835ed37glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10424dec72c9b492c176af9813be3105518e91835ed37glennrp               "  Setting ping_have_tRNS=MagickTrue.");
10425dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10426dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10427dec72c9b492c176af9813be3105518e91835ed37glennrp
10428dec72c9b492c176af9813be3105518e91835ed37glennrp  if (logging != MagickFalse)
10429dec72c9b492c176af9813be3105518e91835ed37glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10430dec72c9b492c176af9813be3105518e91835ed37glennrp      "  Writing PNG header chunks");
10431dec72c9b492c176af9813be3105518e91835ed37glennrp
10432dec72c9b492c176af9813be3105518e91835ed37glennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
10433dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_bit_depth,ping_color_type,
10434dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_interlace_method,ping_compression_method,
10435dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_filter_method);
10436dec72c9b492c176af9813be3105518e91835ed37glennrp
10437dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
10438dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10439dec72c9b492c176af9813be3105518e91835ed37glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
10440dec72c9b492c176af9813be3105518e91835ed37glennrp
10441dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10442dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10443dec72c9b492c176af9813be3105518e91835ed37glennrp          for (i=0; i< (ssize_t) number_colors; i++)
10444dec72c9b492c176af9813be3105518e91835ed37glennrp          {
10445dec72c9b492c176af9813be3105518e91835ed37glennrp            if (i < ping_num_trans)
10446dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10447dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10448dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10449dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10450dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10451dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue,
10452dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10453dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) ping_trans_alpha[i]);
10454dec72c9b492c176af9813be3105518e91835ed37glennrp             else
10455dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10456dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d)",
10457dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10458dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10459dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10460dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue);
10461dec72c9b492c176af9813be3105518e91835ed37glennrp           }
10462dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10463dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10464dec72c9b492c176af9813be3105518e91835ed37glennrp
104650d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
104660d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
104673d627862fb79aad8a20be4f1587f0b8761db441aglennrp     (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
104680d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
104690d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
104700d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
104710d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
10472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
10473c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
10474c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
104753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10476c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
104770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10478c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
10479c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
10480c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
10481c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
10482c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
1048326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
10484c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
10485c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
10486c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
10487ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10488ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          "  Setting up iCCP chunk");
104896647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
1049016ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
10491e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
10492c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
10493e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
10494e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
10495e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
10496c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
10497918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                       ping_have_iCCP = MagickTrue;
10498c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
1049926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
105000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10501c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
105023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10503c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
10504c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
10505ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10506ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      "  Setting up zTXT chunk with uuencoded ICC");
10507cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
10508c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
10509c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
10510c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
10511ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  ping_have_iCCP = MagickTrue;
10512c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
10513c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
105140b206f5daa453dc1035db5890cabc899736dc2d0glennrp
10515c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
10516c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10517c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
105180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10519c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
10520c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
105210d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
105223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
105233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
10526ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_have_iCCP != MagickTrue &&
10527ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      (ping_have_sRGB != MagickFalse ||
10528ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1053026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
1053126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1053226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
1053326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
1053426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
1053526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
1053626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
105380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1053926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
10540cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
10541cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
10542918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp
10543918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB = MagickTrue;
1054426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1054626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
105475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105502cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
10551918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_iCCP == MagickFalse &&
10552918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB == MagickFalse &&
105532cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
1055426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
1055526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
105563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
105573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
105593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
105603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
105613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
105623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
105653b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1056826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
105692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10570918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp      if (ping_exclude_cHRM == MagickFalse && ping_have_sRGB == MagickFalse)
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1057226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
1057326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
1057426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
1057526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
1057626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
10577918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                Note: if cHRM+gAMA == sRGB write sRGB instead.
1057826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
1057926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
1058026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
1058126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
1058226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
1058326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
1058426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1058526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1058626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1058726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1058826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1058926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1059026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1059126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1059226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1059326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1059426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1059526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1059626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1059726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10599dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1060026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1060126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1060226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10603c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1060426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
106058fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10606c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10607c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10608c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10609c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10610c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10611c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10612c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10613c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10614c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10615c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10616c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10617c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10618c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10619c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1062026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10621991d11dd9c33e65872778b81aff1347cd2878154glennrp
1062226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10623dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1062426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1062526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1062626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1062726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1062826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1062926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10630823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
106318fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10632823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10633823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10634823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10635823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10636823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10637823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10638823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10639823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10640823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10641823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10642823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10643823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10644823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1064526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10646dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10647dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10648dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
106494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10650dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1065126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1065226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1065326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1065426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10655dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1065626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1065726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1065826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1065926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1066026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10661dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10662dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10663dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10664fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
10665fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (ping_exclude_tIME == MagickFalse)
10666fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
10667fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      const char
10668fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        *timestamp;
10669fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
1067039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      if (image->taint == MagickFalse)
10671fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
1067239d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          timestamp=GetImageOption(image_info,"png:tIME");
1067339d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1067439d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          if (timestamp == (const char *) NULL)
10675fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            timestamp=GetImageProperty(image,"png:tIME",exception);
10676fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
1067739d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1067839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      else
1067939d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp        {
1068039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1068139d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp             "  Reset tIME in tainted image");
1068239d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1068339d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          timestamp=GetImageProperty(image,"date:modify",exception);
1068439d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp        }
1068539d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1068639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      if (timestamp != (const char *) NULL)
1068739d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          write_tIME_chunk(image,ping,ping_info,timestamp,exception);
10688fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
10689fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
106906647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
10691da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10692da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1069316ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10694da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10695da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10696da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10697da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10698da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10699da8f3a7bfddac2680a3069a490db541e7944edafglennrp
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10701991d11dd9c33e65872778b81aff1347cd2878154glennrp
1070239992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10703991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
107043b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
107050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
107080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10709991d11dd9c33e65872778b81aff1347cd2878154glennrp
107100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
107110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
107120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
107130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
107140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10715991d11dd9c33e65872778b81aff1347cd2878154glennrp
107160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
107170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
107190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
107200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
107210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
107220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107233b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
107240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
107250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10726c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
107270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
107280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
107290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
107300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
107310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
107320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10733991d11dd9c33e65872778b81aff1347cd2878154glennrp
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10735cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10736da8f3a7bfddac2680a3069a490db541e7944edafglennrp
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10738991d11dd9c33e65872778b81aff1347cd2878154glennrp
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10740cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1074226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
107454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1074626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1074726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1074826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1074926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1075026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1075126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1075203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1075326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1075426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1075526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1075626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1075726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1075826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
107629c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
107649c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10773b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10774b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
107757202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10777b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10779b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10781b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10782b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10783b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10785b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10787b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10789b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10790b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107923b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
107933b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10795b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10796b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
107970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10798b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10799e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108010997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=AcquireVirtualMemory(rowbytes,sizeof(*ping_pixels));
108020997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
10803edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Allocation of memory for pixels failed");
108040997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
108050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108095f766ef8b0cd9906c2c3a56d845828380a251073cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10810ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10811edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation for quantum_info failed");
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
108144b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
108168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10818fd164d2bf84b111e304959af5698757d60e9b8aeglennrp       !mng_info->write_png48 && !mng_info->write_png64 &&
108198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
108208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
108228d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
108238d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1082616ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
108280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
108323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10835bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10837d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
108383b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108393b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10840a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1084116ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
108420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1084316ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
108450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1084816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1084916ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
108513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10855bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10856cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
108623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1086316ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1086416ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10868bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10869cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
108710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108723b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10873b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10874b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
108750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10876cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
10877af9320404a7b05014476f844b11110157a21b73eglennrp
10878af9320404a7b05014476f844b11110157a21b73eglennrp          status=SetImageProgress(image,LoadImageTag,
10879af9320404a7b05014476f844b11110157a21b73eglennrp              (MagickOffsetType) (pass * image->rows + y),
10880af9320404a7b05014476f844b11110157a21b73eglennrp              num_passes * image->rows);
1088144c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
10882af9320404a7b05014476f844b11110157a21b73eglennrp          if (status == MagickFalse)
10883af9320404a7b05014476f844b11110157a21b73eglennrp            break;
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10891fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png48 && !mng_info->write_png64 &&
10892fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png32) && (image_matte != MagickFalse ||
10893fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
10894fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (mng_info->IsPalette) && ping_have_color == MagickFalse)
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1089616ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
108978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
108980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10902bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1090416ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
109052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1090616ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
109082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1091216ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1091316ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
109142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1091616ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1091716ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
109182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
109208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10925b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
109263b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10927b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
109292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1093016ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1093116ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
10932b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
109332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109343b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10935b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
109372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10938cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
109392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10940af9320404a7b05014476f844b11110157a21b73eglennrp            status=SetImageProgress(image,LoadImageTag,
10941af9320404a7b05014476f844b11110157a21b73eglennrp              (MagickOffsetType) (pass * image->rows + y),
10942af9320404a7b05014476f844b11110157a21b73eglennrp              num_passes * image->rows);
1094344c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
10944af9320404a7b05014476f844b11110157a21b73eglennrp            if (status == MagickFalse)
10945af9320404a7b05014476f844b11110157a21b73eglennrp              break;
109468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
109478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
109488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
109490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1095216ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
109538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
109540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10957fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            if ((image_depth > 8) ||
10958fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 ||
109598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
10960fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 ||
10961fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png64 ||
10962fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
109638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
109648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10965b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
10966862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
109672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1096816ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
109698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
109702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
109738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1097416ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1097516ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
109762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1097816ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1097916ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
109808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109812cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
109838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1098416ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10985cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1098616ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
109872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
109898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
109918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1099416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1099516ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
109962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1099816ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1099916ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
110002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110013b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
11002b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
110042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11005cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
11006af9320404a7b05014476f844b11110157a21b73eglennrp
11007af9320404a7b05014476f844b11110157a21b73eglennrp                status=SetImageProgress(image,LoadImageTag,
11008af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) (pass * image->rows + y),
11009af9320404a7b05014476f844b11110157a21b73eglennrp                  num_passes * image->rows);
1101044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
11011af9320404a7b05014476f844b11110157a21b73eglennrp                if (status == MagickFalse)
11012af9320404a7b05014476f844b11110157a21b73eglennrp                  break;
11013b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
110148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
110152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
11017fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            /* not ((image_depth > 8) ||
11018fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 || mng_info->write_png32 ||
11019fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 || mng_info->write_png64 ||
11020fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
11021fd164d2bf84b111e304959af5698757d60e9b8aeglennrp             */
110228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
110238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
110248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
110258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
110268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
110278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
110292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
110318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
110328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
110332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
110358640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
110368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
110378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
110392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1104016ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
110412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1104216ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
110438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1104644757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
110474bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
110484bf89731a90c6e03598950223e19e7be7b95d630glennrp
1104916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1105016ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1105144757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
110522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
110548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
110558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
110568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
110582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1105916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
11060cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1106116ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
110628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
110632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
110658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1106616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1106716ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
110682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110695eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
110705eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
110715eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110721a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
110735eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
110745eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110755eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
110765eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
110775eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
110788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
11079cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
110802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11081af9320404a7b05014476f844b11110157a21b73eglennrp                status=SetImageProgress(image,LoadImageTag,
11082af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) (pass * image->rows + y),
11083af9320404a7b05014476f844b11110157a21b73eglennrp                  num_passes * image->rows);
1108444c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
110858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
110868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110878640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
11088af9320404a7b05014476f844b11110157a21b73eglennrp            }
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
110928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
11093b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
11094b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11099b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
111000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11102e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
111030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11105e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
111060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111105d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
111150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111195d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
111240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11129a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11131823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1113326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1113426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1113526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1113626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1113726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1113826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
111392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1114016ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
11141a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11142e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      /* Don't write any "png:" or "jpeg:" properties; those are just for
11143e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       * "identify" or for passing through to another JPEG
11144e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       */
11145e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      if ((LocaleNCompare(property,"png:",4) != 0 &&
11146a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp           LocaleNCompare(property,"jpeg:",5) != 0) &&
11147e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp
11148a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11149a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
11150a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
11151823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
11152a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
11153a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11154a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
11155a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
11156a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1115726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
11158c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
11159c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
11160a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy
11161ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
11162a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,
11163a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy                 (png_alloc_size_t) sizeof(png_text));
11164a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
11165a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
11166a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
11167c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
11168c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
11169c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
111702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11171c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
11172c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
111732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11174c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
11175c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
111762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11177c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1117826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
11179c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
11180c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
11181c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
11182c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1118326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
111842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11185c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
11186c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
11187c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11188c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
11189c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11190c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11191cbc9215c23fce410bf0bea825dee908c15271bb3glennrp                  "    keyword: '%s'",text[0].key);
11192c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
11193c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11194c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
11195c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
11196c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1119726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1119826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1119926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
11203cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
112080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
112100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
112145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
112155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1122503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
112365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
112395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
112433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
112450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
112473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
112483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
11251edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
112520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
112583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112590997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
112603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1126116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1126216ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1126316ea139d53d867211d3bb0fa859a83de653f687ecristy
1126416ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1126516ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1126616ea139d53d867211d3bb0fa859a83de653f687ecristy
11267b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
11268b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
11269b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
11270b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1127116ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
11272b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
112760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11277868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
11278edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
11279edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
11280edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
11281edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   /* }  for navigation to beginning of SETJMP-protected block. Revert to
11282edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    *    Throwing an Exception when an error occurs.
11283edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    */
11284edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
11287edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
112893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
113023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
113033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1130816ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1130916ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
113163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1131716ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1131816ea139d53d867211d3bb0fa859a83de653f687ecristy%
113193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
113203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
113223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
113243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
113255d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113275a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
113285a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
113293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
113303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
113315a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
113325a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
11333e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
11334130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
11335130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
11336130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
11337e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
11338e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
11339e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
113405a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
113415a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
113423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
113435a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
113445a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
113455a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
113463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
113495a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
113505a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
113515a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
113525a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
113535a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
113543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
113563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
113573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
113580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
113595a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
113605a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
113613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11362fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG48:   A 16-bit per sample RGB PNG datastream is written.  The tRNS
11363fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               chunk can be present to convey binary transparency by naming
11364fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               one of the colors as transparent.  If the image has more
11365fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               than one transparent color, has semitransparent pixels, or
11366fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               has an opaque pixel with the same RGB components as the
11367fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparent color, an image is not written.
11368fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
11369fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG64:   A 16-bit per sample RGBA PNG is written.  Partial
11370fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparency is permitted, i.e., the alpha sample for
11371fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               each pixel can have any value from 0 to 65535. The alpha
11372fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               channel is present even if the image is fully opaque.
11373fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
113745830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%    o PNG00:   A PNG that inherits its colortype and bit-depth from the input
113755830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               image, if the input was a PNG, is written.  If these values
11376c1e07709d63f88437cf56ddbc6b3889a96711346glennrp%               cannot be found, or if the pixels have been changed in a way
11377c1e07709d63f88437cf56ddbc6b3889a96711346glennrp%               that makes this impossible, then "PNG00" falls back to the
11378c1e07709d63f88437cf56ddbc6b3889a96711346glennrp%               regular "PNG" format.
113795830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%
113803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
11383bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
11384bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
11385bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
113863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
113903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
114013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11403fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               If the image cannot be written without loss with the
11404fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               requested bit-depth and color-type, a PNG file will not
11405fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               be written, a warning will be issued, and the encoder will
11406fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               return MagickFalse.
114075a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
114083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
114093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
114103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
114115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1141216ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
114163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
114173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
114203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
114213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
114243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
114263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
11427bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
11428bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
114293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
114313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
114323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
11433bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
114343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11435bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
114363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114373241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
114380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
11439d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
114400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
114410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
114420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
11443cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
114440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
11445d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
11446d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
114475d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
11448d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
11449d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
11450d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
11451d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
114520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
114533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
114553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1145616ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
114573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1145921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1146021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1146121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
114663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
114683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
114693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
114715c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
114725c7cf4e469a4dad7e277783749155932252c52dfglennrp
114733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
114753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
114793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11481fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
114823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1148673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
114870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
114900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
114953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
11496a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
114973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
11504fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png48=LocaleCompare(image_info->magick,"PNG48") == 0;
11505fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png64=LocaleCompare(image_info->magick,"PNG64") == 0;
115063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11507092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:format");
11508b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
115095a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp  if (value != (char *) NULL || LocaleCompare(image_info->magick,"PNG00") == 0)
11510b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
11511f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11512f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp         "  Format=%s",value);
11513f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11514fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png8 = MagickFalse;
11515fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png24 = MagickFalse;
11516fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png32 = MagickFalse;
11517fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png48 = MagickFalse;
11518fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png64 = MagickFalse;
11519fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11520b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
11521b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
11522b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11523b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11524b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11525b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11526b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11527b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11528fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11529fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png48") == 0)
11530fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png48 = MagickTrue;
11531fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11532fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png64") == 0)
11533fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png64 = MagickTrue;
115345830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115355a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp      else if ((LocaleCompare(value,"png00") == 0) ||
115365a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp         LocaleCompare(image_info->magick,"PNG00") == 0)
115375830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        {
115383398b5b62521b49754d9391aae9e4511857bd63bglennrp          /* Retrieve png:IHDR.bit-depth-orig and png:IHDR.color-type-orig. */
115393398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.bit-depth-orig",exception);
115406647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11541f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11542f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11543f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11544f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited bit depth=%s",value);
115456647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11546f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"1") == 0)
11547f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 1;
115486647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
115495a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"2") == 0)
11550f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 2;
115516647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
115525a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"4") == 0)
11553f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 4;
115546647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11555f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"8") == 0)
11556f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 8;
115576647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11558f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"16") == 0)
11559f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 16;
11560f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
115616647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
115623398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.color-type-orig",exception);
115636647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11564f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11565f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11566f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11567f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited color type=%s",value);
115686647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11569f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"0") == 0)
11570f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 1;
115716647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11572f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"2") == 0)
11573f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 3;
115746647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11575f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"3") == 0)
11576f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 4;
115776647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11578f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"4") == 0)
11579f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 5;
115806647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11581f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"6") == 0)
11582f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 7;
11583f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
115845830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        }
115855830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
115865830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
115883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115899c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
115909c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115919c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115969c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
115979c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115989c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1160017f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      if (image->alpha_trait != UndefinedPixelTrait)
11601def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,TrueColorAlphaType,exception);
116020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116039c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1160416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
116050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1160616ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
116103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116119c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
116129c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
116139c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
1161447da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
116150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11616def23e5d7331b1a13ed593b6d6aca516da382328cristy      (void) SetImageType(image,TrueColorAlphaType,exception);
1161716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11620fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48)
11621fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11622fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 2 */ 3;
11623fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11624fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
11625fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
1162617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      if (image->alpha_trait != UndefinedPixelTrait)
11627def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,TrueColorAlphaType,exception);
11628fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11629fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else
116304dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorType,exception);
11631fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
116324dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11633fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11634fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11635fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png64)
11636fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11637fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 6 */  7;
11638fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11639fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
1164047da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
11641fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11642def23e5d7331b1a13ed593b6d6aca516da382328cristy      (void) SetImageType(image,TrueColorAlphaType,exception);
116434dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11644fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11645fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11646092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:bit-depth");
116478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
116483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
116519c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
116520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116549c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
116550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
116579c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
116580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
116609c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
116610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
116639c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
116640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11665bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1166616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11667bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11668bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11669bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11670bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
116713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
116729c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11673bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
116743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11676092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:color-type");
116770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
116813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
116829c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
116830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1168416ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1168516ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1168616ea139d53d867211d3bb0fa859a83de653f687ecristy
116873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116889c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
116890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
116919c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
116920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
116949c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
116950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
116979c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
116980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11699bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1170016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11701bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11702bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11703bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11704bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
117053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
117069c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11707d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
117083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
117093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
117110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117120dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
117130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
117140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117155d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
117160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
117170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
117180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
117190e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
117200e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
117220e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117235d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
117245d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
117250e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
117260dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
117270dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
117280dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11729aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11730aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11731aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
117320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117330e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
117340e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
117350e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
117360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117370e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
117380e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
117390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
117400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
117420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
117430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11745104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
117460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
117470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1174826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1174926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11750a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1175126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1175226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1175326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1175426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1175526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1175626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1175726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1175826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11759fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  mng_info->ping_exclude_tIME=MagickFalse;
11760a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1176126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1176226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1176326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1176426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
117658d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
117668d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11767092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:preserve-colormap");
117688d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
117698b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:preserve-colormap");
117708d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
117718d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
117728d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11773ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  mng_info->ping_preserve_iCCP=MagickFalse;
11774ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11775ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  value=GetImageOption(image_info,"png:preserve-iCCP");
11776ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value == NULL)
11777ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     value=GetImageArtifact(image,"png:preserve-iCCP");
11778ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value != NULL)
11779ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     mng_info->ping_preserve_iCCP=MagickTrue;
11780ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11781ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  /* These compression-level, compression-strategy, and compression-filter
117821868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
117831868258559ddf946fa73ef72dd43507b32623705glennrp   */
11784092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-level");
117851868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
117868b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-level");
117871868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
117881868258559ddf946fa73ef72dd43507b32623705glennrp  {
117891868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
117901868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
117911868258559ddf946fa73ef72dd43507b32623705glennrp       */
117921868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
117931868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
117941868258559ddf946fa73ef72dd43507b32623705glennrp
117950ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
117961868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
117971868258559ddf946fa73ef72dd43507b32623705glennrp
117981868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
117991868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
118001868258559ddf946fa73ef72dd43507b32623705glennrp
118011868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118021868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
118031868258559ddf946fa73ef72dd43507b32623705glennrp
118041868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118051868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
118061868258559ddf946fa73ef72dd43507b32623705glennrp
118071868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118081868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
118091868258559ddf946fa73ef72dd43507b32623705glennrp
118101868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
118111868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
118121868258559ddf946fa73ef72dd43507b32623705glennrp
118131868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
118141868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
118151868258559ddf946fa73ef72dd43507b32623705glennrp
118161868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
118171868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
118181868258559ddf946fa73ef72dd43507b32623705glennrp
118191868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
118201868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
118211868258559ddf946fa73ef72dd43507b32623705glennrp
118221868258559ddf946fa73ef72dd43507b32623705glennrp      else
1182316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118241868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118251868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
118261868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118271868258559ddf946fa73ef72dd43507b32623705glennrp    }
118281868258559ddf946fa73ef72dd43507b32623705glennrp
11829092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-strategy");
118301868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118318b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-strategy");
118321868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118331868258559ddf946fa73ef72dd43507b32623705glennrp  {
118341868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118351868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
118361868258559ddf946fa73ef72dd43507b32623705glennrp
118371868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
118381868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
118391868258559ddf946fa73ef72dd43507b32623705glennrp
118401868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118411868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
118421868258559ddf946fa73ef72dd43507b32623705glennrp
118431868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1184498c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
118451868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1184698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1184798c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1184898c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
118491868258559ddf946fa73ef72dd43507b32623705glennrp
118501868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1185198c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
118521868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1185398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1185498c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1185598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
118561868258559ddf946fa73ef72dd43507b32623705glennrp
118571868258559ddf946fa73ef72dd43507b32623705glennrp      else
1185816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118591868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118601868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
118611868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118621868258559ddf946fa73ef72dd43507b32623705glennrp    }
118631868258559ddf946fa73ef72dd43507b32623705glennrp
11864092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-filter");
118651868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118668b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-filter");
118671868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118681868258559ddf946fa73ef72dd43507b32623705glennrp  {
118691868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
118701868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
118711868258559ddf946fa73ef72dd43507b32623705glennrp       *
118721868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
118731868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
118741868258559ddf946fa73ef72dd43507b32623705glennrp       */
118751868258559ddf946fa73ef72dd43507b32623705glennrp
118761868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118771868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
118781868258559ddf946fa73ef72dd43507b32623705glennrp
11879b19b8125320afb5954bd73b82d00700e8ed9e984cristy      else if (LocaleCompare(value,"1") == 0)
118801868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
118811868258559ddf946fa73ef72dd43507b32623705glennrp
118821868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118831868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
118841868258559ddf946fa73ef72dd43507b32623705glennrp
118851868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118861868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
118871868258559ddf946fa73ef72dd43507b32623705glennrp
118881868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118891868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
118901868258559ddf946fa73ef72dd43507b32623705glennrp
118911868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118921868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
118931868258559ddf946fa73ef72dd43507b32623705glennrp
118941868258559ddf946fa73ef72dd43507b32623705glennrp      else
1189516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118961868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118971868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
118981868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118991a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  }
1190003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
119011a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  for (source=0; source<8; source++)
119025c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
119031a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    value = NULL;
11904acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
119052dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 0)
119062dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunks");
119072dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119082dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 1)
119092dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunks");
119102dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119112dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 2)
119122dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunk");
119132dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119142dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 3)
119152dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunk");
119162dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119172dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 4)
119182dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunks");
119192dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119202dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 5)
119212dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunks");
119222dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119232dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 6)
119242dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunk");
119252dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119262dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 7)
119272dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunk");
1192826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
119291a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (value == NULL)
119301a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp       continue;
119311a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp
119321a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (source < 4)
119331a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickTrue;
119341a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    else
119351a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickFalse;
1193626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1193703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
119382cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
119391a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        if (source == 0 || source == 2)
119401a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119411a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:exclude-chunk=%s found in image options.\n", value);
119421a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 1 || source == 3)
119432cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119442cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
119451a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 4 || source == 6)
119462cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119471a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image options.\n", value);
119481a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else /* if (source == 5 || source == 7) */
119491a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119501a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
119512cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1195203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
119531a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (IsOptionMember("all",value) != MagickFalse)
119541a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
119551a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_bKGD=excluding;
119561a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_cHRM=excluding;
119571a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_date=excluding;
119581a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_EXIF=excluding;
119591a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_gAMA=excluding;
119601a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_iCCP=excluding;
119611a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=excluding; */
119621a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_oFFs=excluding;
119631a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_pHYs=excluding;
119641a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_sRGB=excluding;
119651a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tEXt=excluding;
11966fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding;
119671a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tRNS=excluding;
119681a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_vpAg=excluding;
119691a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zCCP=excluding;
119701a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zTXt=excluding;
119711a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
11972280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp
11973689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("none",value) != MagickFalse)
119741a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
11975a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_bKGD=excluding != MagickFalse ? MagickFalse :
11976a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11977a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_cHRM=excluding != MagickFalse ? MagickFalse :
11978a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11979a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_date=excluding != MagickFalse ? MagickFalse :
11980a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11981a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_EXIF=excluding != MagickFalse ? MagickFalse :
11982a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11983a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_gAMA=excluding != MagickFalse ? MagickFalse :
11984a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11985a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_iCCP=excluding != MagickFalse ? MagickFalse :
11986a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
119871a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=!excluding; */
11988a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_oFFs=excluding != MagickFalse ? MagickFalse :
11989a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11990a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_pHYs=excluding != MagickFalse ? MagickFalse :
11991a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11992a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_sRGB=excluding != MagickFalse ? MagickFalse :
11993a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11994a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tEXt=excluding != MagickFalse ? MagickFalse :
11995a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11996fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding != MagickFalse ? MagickFalse :
11997fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          MagickTrue;
11998a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tRNS=excluding != MagickFalse ? MagickFalse :
11999a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12000a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_vpAg=excluding != MagickFalse ? MagickFalse :
12001a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12002a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zCCP=excluding != MagickFalse ? MagickFalse :
12003a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12004a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zTXt=excluding != MagickFalse ? MagickFalse :
12005a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
120061a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
1200703812ae402fb53d548f0e1d7d14720768f803c2dglennrp
12008689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("bkgd",value) != MagickFalse)
120091a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_bKGD=excluding;
120102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12011689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("chrm",value) != MagickFalse)
120121a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_cHRM=excluding;
12013a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
12014689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("date",value) != MagickFalse)
120151a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_date=excluding;
120162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12017689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("exif",value) != MagickFalse)
120181a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_EXIF=excluding;
120192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12020689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("gama",value) != MagickFalse)
120211a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_gAMA=excluding;
120222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12023689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("iccp",value) != MagickFalse)
120241a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iCCP=excluding;
120252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12026689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
12027689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("itxt",value) != MagickFalse)
120281a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iTXt=excluding;
12029689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
120302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12031689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("offs",value) != MagickFalse)
120321a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_oFFs=excluding;
120332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12034689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("phys",value) != MagickFalse)
120351a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_pHYs=excluding;
120362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12037689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("srgb",value) != MagickFalse)
120381a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_sRGB=excluding;
120392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12040689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("text",value) != MagickFalse)
120411a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tEXt=excluding;
120422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12043fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (IsOptionMember("time",value) != MagickFalse)
12044fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      mng_info->ping_exclude_tIME=excluding;
12045fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
12046689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("trns",value) != MagickFalse)
120471a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tRNS=excluding;
12048a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
12049689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("vpag",value) != MagickFalse)
120501a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_vpAg=excluding;
120512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12052689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("zccp",value) != MagickFalse)
120531a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zCCP=excluding;
120542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12055689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("ztxt",value) != MagickFalse)
120561a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zTXt=excluding;
1205726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1205826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
120591a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  if (logging != MagickFalse)
1206026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1206126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120625d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1206326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1206426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1206526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1206626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1206726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1206826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
12069a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
12070a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12071a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1207226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1207326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1207426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1207526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1207626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1207726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1207826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1207926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
12081689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
1208226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1208326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
12085689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
12086689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp
1208726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1208826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1209026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1209126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1209326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1209426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1209626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1209726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
12099fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (mng_info->ping_exclude_tIME != MagickFalse)
12100fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12101fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          "    tIME");
12102a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
12103a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12104a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1210526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1210626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1210726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1210826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1210926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1211126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1211226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1211426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1211526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
12116b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
121173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1211816ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
121193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
121210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
121240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
121263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
121273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
121293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
121313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1213216ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
121333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
121343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
121353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
121363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
121383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
121393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1214103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
121423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
121433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
121453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
121463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
121483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
121493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
121513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
121533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
121543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
121563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
121573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12158bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1215959575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
121603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
121613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
12163fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
121643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
121663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
121673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
121687e99a06aa771c9e270e7940731dbf9f2ab2c09b1glennrp  length=0;
121693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
12171def23e5d7331b1a13ed593b6d6aca516da382328cristy  transparent=image_info->type==GrayscaleAlphaType ||
1217244c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp     image_info->type==TrueColorAlphaType ||
1217344c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp     image->alpha_trait != UndefinedPixelTrait;
121743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121754b917593e694424be469d250448c05c878663812glennrp  jng_alpha_sample_depth = 0;
121764b917593e694424be469d250448c05c878663812glennrp
1217759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1217859575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1217959575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1218059575fa5c228308a41d7f5028390be2083aaaf6dglennrp
12181750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1218259575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1218359575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1218459575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1218559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
121863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12187d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  length=0;
12188d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
121898fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
121903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
121920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
121943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
121953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1219616ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
121970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
121990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
122013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
122043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
122060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1220716ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
122083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
122093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
12210151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MagickPathExtent);
122118a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      jpeg_image->alpha_trait=UndefinedPixelTrait;
122128f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1221316ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1221416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
12216151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(jpeg_image_info->filename,MagickPathExtent,
122173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
122183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1221959575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1222059575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1222159575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1222259575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1222359575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1222459575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
122253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
122273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
12229def23e5d7331b1a13ed593b6d6aca516da382328cristy  if (image_info->type != TrueColorAlphaType && image_info->type !=
12230f1d8548abecaf5ca89d453fd9fc0cde77d20672bdirk    TrueColorType && SetImageGray(image,exception))
122313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
122323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1223359575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1223459575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1223559575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1223659575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1223759575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1223859575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
122398fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (transparent != 0)
1224059575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1224159575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224259575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1224359575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224459575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1224559575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224659575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1224759575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1224859575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1224959575fa5c228308a41d7f5028390be2083aaaf6dglennrp
122508fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
122513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
122533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
122553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
122563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1225716ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
122583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1225916ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
1226044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp          if (status == MagickFalse)
1226144c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1226244c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
122663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12267151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MagickPathExtent);
12268151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MagickPathExtent);
122693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12271cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
12272cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
12273cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
122743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1227516ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1227816ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
122803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
122813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1228416ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
122853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1228716ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
1228844c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp          if (status == MagickFalse)
1228944c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1229044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
122913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12292151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MagickPathExtent);
12293151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MagickPathExtent);
122943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
122983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1229916ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
123003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
123010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
123033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12304e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
12305e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
123063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
123103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
123113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
123123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
123153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
123163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1231703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
123184e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
123194e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
123203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
123253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
123273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
123283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
123293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
123323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12333f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
123340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12336f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
123370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
123400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
123430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
123460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
123490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
123520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
123550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
123580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
12364cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
123653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
123683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123708fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
123723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
123743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
123803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12381bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
123833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
123853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
123863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
123873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
12388bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
123893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1239003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
123923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
123933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
123963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
123973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
123983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
123993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
124013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
124053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
124083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
124103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1241103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
124120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
12414e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12415cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12416e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
124170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12419e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12420cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12421e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
124220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
124293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
124323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
124343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1243503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1243635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
124373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
124383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
124453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
124463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
124493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
124513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1245203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
124533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1245435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1245535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
124563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1245735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1245835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
124593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1246035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1246135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
124623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1246335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1246435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
124653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1247016ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
124713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
124743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
124763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1247703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
124783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
124793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1248035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1248116ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
124820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1248335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1248416ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
124850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
124873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
124903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
124923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1249335ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1249416ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
124950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1249635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1249716ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
124980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
125003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
125033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1250416ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1250516ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
125163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
125173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1252003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12521bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12522bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
125243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
125283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
125303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1253103812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
125323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
125363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125398fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
125403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12543bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
125443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
125453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12546fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy          size_t
125473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
125483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
125503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12552e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12553f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
125543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
125563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12558bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
125605389e5ad63c880fe6885e3b24c76acbdbf63bd61cristy            len=(size_t) (*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
125620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
125643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12566fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image,len);
12567fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                LogPNGChunk(logging,mng_IDAT,len);
12568fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlob(image,len+4,p);
12569fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image, crc32(0,p,(uInt) len+4));
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
125733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
125753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12576e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12577e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125827e99a06aa771c9e270e7940731dbf9f2ab2c09b1glennrp      else if (length != 0)
125833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12587e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
125893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1259003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
125943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
125953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
125963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
126043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
126053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
126063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
126073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
126113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1261216ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
126133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
126143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
12615151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MagickPathExtent);
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
12618151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) FormatLocaleString(jpeg_image_info->filename,MagickPathExtent,"%s",
126193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
126203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1262216ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
126233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12626e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12627e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
126283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1262944c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp  if (status == MagickFalse)
1263044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1263144c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
126323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
126333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
126340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1263559575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1263659575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
12637151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MagickPathExtent);
12638151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MagickPathExtent);
126390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
126430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1264416ea139d53d867211d3bb0fa859a83de653f687ecristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,exception);
126450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
126483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12649e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12650e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
126513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12653e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
126543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12657bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
126583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1265903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
126683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12670cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
126713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1267503812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
126783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
126820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
126883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
126933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
126993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
127013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1270416ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1270516ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
127063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
127103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1271316ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1271416ea139d53d867211d3bb0fa859a83de653f687ecristy%
127153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1271716ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1271816ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1272121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1272203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
127303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
127323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
127333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
127343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12736fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1273716ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
127383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
127393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
127433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1274573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
127463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
127523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
127533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
127543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
127563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1275716ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
127583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
127613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
127623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1276816ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1276916ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
127753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
127763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1277821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
127793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1278103812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1278203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1278303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
127893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
127933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
127943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
127983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12801bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
128033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
128063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
128083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12811bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
128123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
128133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12814bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
128163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12818d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
128193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
128213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
128263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
128293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12832fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1283316ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1284173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
128423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
128483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
128573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
128603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
128683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
128753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
128763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
128793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128812dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "  Checking input image(s)\n"
128822dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    Image_info depth: %.20g,    Type: %d",
128832dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) image_info->depth, image_info->type);
128843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
128863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
128873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
128880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12890280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           "    Scene: %.20g\n,   Image depth: %.20g",
12891280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           (double) scene++, (double) p->depth);
128920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1289317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (p->alpha_trait != UndefinedPixelTrait)
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
128960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
129000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
129023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
129040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
129080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12911e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
129120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
129160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
129183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
129203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
129243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
129263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
129283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
129293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
129303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
129313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
129343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
129363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
129373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
129393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
129403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
129423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
129443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
129503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
129553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
129563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
129573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
129583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
129603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
129613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
129623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
129633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
129643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
129653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
129663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
129673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
129683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
129713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
129723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
129743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
129763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
129783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
129790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
129823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
129830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
129853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
129860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1298717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (next_image->alpha_trait != UndefinedPixelTrait)
129883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
129890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
1299117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy          if ((next_image->alpha_trait != UndefinedPixelTrait) ||
12992dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy               next_image->page.x || next_image->page.y ||
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
129960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
129983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
129990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
130010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
130043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
130050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
130093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
130103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
1301117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (image->alpha_trait != UndefinedPixelTrait)
130123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
130130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
130153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
13016f1d8548abecaf5ca89d453fd9fc0cde77d20672bdirk            if (SetImageGray(image,exception) == MagickFalse)
130173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
130183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
130193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
130203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
130213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
130253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
130283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
130293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
130303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
130313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
130323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
130330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
130353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
130360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
130383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
130393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
130400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1304216ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1304316ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
130443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
130450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
130473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
130483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
130493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
130503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
130513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
130533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
130563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
130573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
130583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
130603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
130613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
130623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
130633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
130653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
130663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
130703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
130723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
130733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
130743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
130753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
130763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
130773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
130783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
130793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
130803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
130823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
130830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
130853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
130863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
130873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
130883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
130893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
130903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
130913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
130923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
130933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
130943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
130953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
130963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
130970261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
13098d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
13099d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1310016ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1310116ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
13102d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
13103d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
13104d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
131083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
13110cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
13111cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
131123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
131133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
131140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
131163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
131170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
131193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
131200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
131223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
13123d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp            (final_delay != 25) && (final_delay != 50) && (1UL*final_delay !=
131243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
131293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
131303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
131333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
131343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
131373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
131393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
131403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1314103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
131424e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
131434e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
131463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
131473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
131493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
131540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
131573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
131630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
131663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
131703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
131750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
131783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
131840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
131873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
131903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
13191092ec8d083fedaedfb7792995e7ea42164553cffcristy     option=GetImageOption(image_info,"mng:need-cacheoff");
131923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
131933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
131953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
131963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
131983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
131993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
132013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
13202bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1320303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
132043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
132053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
132063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
132073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
132093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
132103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
132113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
132143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
132163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1321703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
132183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
132193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
132203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
132213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
132220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
132243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
132250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
132273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
132280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
132303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13232e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
13233e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
132340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
132363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13237e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
132380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13241e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
132423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
132443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
132453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
132473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
132483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
132493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
132503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
132513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
132543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
132563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1325703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
132580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
13260e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13261cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13262e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
132630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
13265e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13266cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13267cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
132680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
132703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
132713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
132723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
132753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
132773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
132803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
132813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
132823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1328303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1328435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
132853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
132863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
132873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
132883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
132903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
132923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
132933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
132963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
132973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
132983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1329903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
133003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1330135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1330235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
133033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1330435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1330535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
133063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1330735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1330835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
133093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1331035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1331135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
133123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
133133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
133143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
133153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1331716ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
133183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
133213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
133233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1332403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
133250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
133273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1332835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1332916ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
133300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1333135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1333216ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
133330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
133353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
133383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
133403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1334135ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1334216ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
133430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1334435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1334516ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
133460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
133483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
133513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1335216ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1335316ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
133543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
133553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
133583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
133593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
133613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
133623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
133633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
1336417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     if (write_mng && ((image->alpha_trait != UndefinedPixelTrait) ||
13365dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy         image->page.x > 0 || image->page.y > 0 || (image->page.width &&
133663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
133673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
133683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
133693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
133713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1337203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
133733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
133743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
133753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
133763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
133773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
133783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
133793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
133803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
133813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
133823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
133843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1338503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
133863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
133873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
133883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
133923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
133933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
133943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
133953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
13396bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
133973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
133983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
134003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
134013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
134023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
134033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
134043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1340503812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
134060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13407bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
134083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1340916ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1341016ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1341116ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1341216ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1341316ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1341416ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
134153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
134160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
134183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
134193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
134203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
134213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
134233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
134243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
134253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
134283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
134303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
134313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
134323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
134333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
134363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
134373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
134383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
134393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
134403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
134413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
134423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
134443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
134453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
134463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
134473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
134483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
134493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
134503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
134513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
134523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
134533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
13454bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
134553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
134563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
134583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
134593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1346003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
134610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13462bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
134633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
134643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
134653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
134663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
134673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
134680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
134703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
134713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
134723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
134733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
134743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
134773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
134783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
134803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13481bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
134823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
134833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
134843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
134863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
134883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
134893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
134933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
134943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
134963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
134973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
134983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
135003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1350103812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
135023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
135033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
135043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
135053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
135063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
135073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
135083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
135093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
135103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
135123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
135133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
135153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
135173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
135183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
135203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
135213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
135223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
135243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
135273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
135293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1353003812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
135313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
135333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
135343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
135363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
135393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
135413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1354203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
135433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
135453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
135463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
135473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
135483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
135493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
135503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
135513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
135523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
135533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
135544e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
135553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
135573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
135603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
135613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
135633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
135643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
135683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
135693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
135703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1357116ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
135723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
135733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
135753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
135763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
135802f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13581b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
135828d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
135832f2e514554975d510c88df54de98c6cdc1080f1cglennrp
135842f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
135852f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
135862f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13587a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
135882f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
135892f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
135902f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
135912f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
135922f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
135932f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
135942f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
135952f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13596a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
135972f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
135982f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
135992f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
136002f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1360116ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
136023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
136033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
136043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
136063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
136073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
136083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
136093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
136103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
136113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
136123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
136143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
136153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
136160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
136210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
136233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
136243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
136253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
136263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
136273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
136283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
136293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
136303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1363103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
136323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
136333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
136343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
136353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
136363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
136373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
136383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
136393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
136400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
136423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
136430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
136453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13646d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1364739992b4dd9b12ef752d55b8e402c069698851f72glennrp
136483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
136493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136503bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
136513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
136523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
136530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
136553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
136563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1365739992b4dd9b12ef752d55b8e402c069698851f72glennrp
136583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
136593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
136613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13662d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
136633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13664