png.c revision a701bb35fa5f33c41f4053b39e0f4c4c20ec17d4
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%                                                                             %
217ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 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
528629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
529629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
530629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
531629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
532629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
533629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
534629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
535629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
536629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
537629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
538629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
539629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
540629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
541629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
542629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
543629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
544629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
545629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
546629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
547629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
548629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
549629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
550629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
551629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
552629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
553629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
554629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
555629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
556629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
557629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
558629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
559629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
560629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
561629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
564629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
565629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
566629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
567629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
568629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
569629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const 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: */
574629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
575629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
576629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
577629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
578629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
579629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const png_byte mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
580629f80558ba1e82b0317a3d778deaf195c8e37e5Cristystatic const 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);
1191e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
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
1223120b581ad9516a43c50caedfa1a8cff418488819Cristystatic void PNGType(png_bytep p,const png_byte *type)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1228120b581ad9516a43c50caedfa1a8cff418488819Cristystatic void LogPNGChunk(MagickBooleanType logging, const png_byte *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
2209f9eb20453e3475d44a3833f64c4a662c0106c43edirk#ifdef PNG_SET_USER_LIMITS_SUPPORTED
2210f9eb20453e3475d44a3833f64c4a662c0106c43edirk  /* Reject images with too many rows or columns */
2211f9eb20453e3475d44a3833f64c4a662c0106c43edirk  png_set_user_limits(ping,
2212f9eb20453e3475d44a3833f64c4a662c0106c43edirk    (png_uint_32) MagickMin(0x7fffffffL,
2213f9eb20453e3475d44a3833f64c4a662c0106c43edirk        GetMagickResourceLimit(WidthResource)),
2214f9eb20453e3475d44a3833f64c4a662c0106c43edirk    (png_uint_32) MagickMin(0x7fffffffL,
2215f9eb20453e3475d44a3833f64c4a662c0106c43edirk        GetMagickResourceLimit(HeightResource)));
2216f9eb20453e3475d44a3833f64c4a662c0106c43edirk#endif /* PNG_SET_USER_LIMITS_SUPPORTED */
2217f9eb20453e3475d44a3833f64c4a662c0106c43edirk
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2221faa852bad40107edae19405e76a299057668d795glennrp
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
22240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2247e604a757f40a91c286711c49577eeced17ea97adglennrp  {
2248e604a757f40a91c286711c49577eeced17ea97adglennrp    const char
2249e604a757f40a91c286711c49577eeced17ea97adglennrp      *value;
2250e604a757f40a91c286711c49577eeced17ea97adglennrp
2251e604a757f40a91c286711c49577eeced17ea97adglennrp    value=GetImageOption(image_info,"profile:skip");
2252e604a757f40a91c286711c49577eeced17ea97adglennrp
2253e604a757f40a91c286711c49577eeced17ea97adglennrp    if (IsOptionMember("ICC",value) == MagickFalse)
2254e604a757f40a91c286711c49577eeced17ea97adglennrp    {
2255e604a757f40a91c286711c49577eeced17ea97adglennrp
2256e604a757f40a91c286711c49577eeced17ea97adglennrp       value=GetImageOption(image_info,"png:preserve-iCCP");
2257e604a757f40a91c286711c49577eeced17ea97adglennrp
2258e604a757f40a91c286711c49577eeced17ea97adglennrp       if (value == NULL)
2259e604a757f40a91c286711c49577eeced17ea97adglennrp          value=GetImageArtifact(image,"png:preserve-iCCP");
2260e604a757f40a91c286711c49577eeced17ea97adglennrp
2261e604a757f40a91c286711c49577eeced17ea97adglennrp       if (value != NULL)
2262e604a757f40a91c286711c49577eeced17ea97adglennrp          ping_preserve_iCCP=MagickTrue;
2263201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp
2264201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp#if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED)
2265201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp       /* Don't let libpng check for ICC/sRGB profile because we're going
2266201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp        * to do that anyway.  This feature was added at libpng-1.6.12.
2267cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp        * If logging, go ahead and check and issue a warning as appropriate.
2268201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp        */
2269cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp       if (logging == MagickFalse)
2270cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp          png_set_option(ping, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON);
2271201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp#endif
2272e604a757f40a91c286711c49577eeced17ea97adglennrp    }
2273e604a757f40a91c286711c49577eeced17ea97adglennrp#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
2274e604a757f40a91c286711c49577eeced17ea97adglennrp    else
2275e604a757f40a91c286711c49577eeced17ea97adglennrp    {
2276e604a757f40a91c286711c49577eeced17ea97adglennrp       png_set_keep_unknown_chunks(ping, 1, mng_iCCP, 1);
2277e604a757f40a91c286711c49577eeced17ea97adglennrp    }
2278e604a757f40a91c286711c49577eeced17ea97adglennrp#endif
2279e604a757f40a91c286711c49577eeced17ea97adglennrp  }
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
22822ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#if PNG_LIBPNG_VER < 10700 /* Avoid libpng16 warning */
22832ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp  png_set_keep_unknown_chunks(ping, 2, NULL, 0);
22842ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#else
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
22862ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#endif
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22942feb141b6f74ce425fed3272286fab1f50366bb9glennrp#ifdef PNG_SET_USER_LIMITS_SUPPORTED
229509cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  if (PNG_LIBPNG_VER >= 10400)
22962feb141b6f74ce425fed3272286fab1f50366bb9glennrp    /* Limit the size of the chunk storage cache used for sPLT, text,
2297687361928f16a28ea56e200d00e970e68173cc25glennrp     * and unknown chunks.
22982feb141b6f74ce425fed3272286fab1f50366bb9glennrp     */
2299687361928f16a28ea56e200d00e970e68173cc25glennrp    png_set_chunk_cache_max(ping, 32767);
230009cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  endif
23012feb141b6f74ce425fed3272286fab1f50366bb9glennrp#endif
23022feb141b6f74ce425fed3272286fab1f50366bb9glennrp
23039bf97b6c2143eb20c330346b01e82102cc082725glennrp#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
23049bf97b6c2143eb20c330346b01e82102cc082725glennrp    /* Disable new libpng-1.5.10 feature */
23059bf97b6c2143eb20c330346b01e82102cc082725glennrp    png_set_check_for_invalid_index (ping, 0);
23069bf97b6c2143eb20c330346b01e82102cc082725glennrp#endif
23079bf97b6c2143eb20c330346b01e82102cc082725glennrp
2308991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2309991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2310991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2324991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2328faa852bad40107edae19405e76a299057668d795glennrp
2329faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2330faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2331faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2332faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2333faa852bad40107edae19405e76a299057668d795glennrp
2334fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp  ping_file_depth = ping_bit_depth;
2335fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp
23360d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  /* Swap bytes if requested */
23370d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  if (ping_file_depth == 16)
23380d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  {
23390d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp     const char
2340a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp       *value;
23416647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
2342a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     value=GetImageOption(image_info,"png:swap-bytes");
23436647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
2344a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value == NULL)
2345a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        value=GetImageArtifact(image,"png:swap-bytes");
23466647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
2347a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value != NULL)
2348a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        png_set_swap(ping);
23490d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  }
23500d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp
23515830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  /* Save bit-depth and color-type in case we later want to write a PNG00 */
23525830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  {
23535830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      char
2354151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        msg[MagickPathExtent];
23555830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2356151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(msg,MagickPathExtent,"%d",(int) ping_color_type);
23573398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.color-type-orig",msg,exception);
23585830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2359151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(msg,MagickPathExtent,"%d",(int) ping_bit_depth);
23603398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.bit-depth-orig",msg,exception);
23615830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  }
23625830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2363faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2364faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2365faa852bad40107edae19405e76a299057668d795glennrp
2366faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2367faa852bad40107edae19405e76a299057668d795glennrp
2368faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2370fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       png_set_packing(ping);
2371fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       ping_bit_depth = 8;
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2373faa852bad40107edae19405e76a299057668d795glennrp
2374faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2376faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
237798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2378176b29a003f11fd934137871d574995319408665cristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2379176b29a003f11fd934137871d574995319408665cristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2380176b29a003f11fd934137871d574995319408665cristy    {
2381176b29a003f11fd934137871d574995319408665cristy      image->rendering_intent=UndefinedIntent;
238298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      intent=Magick_RenderingIntent_to_PNG_RenderingIntent(UndefinedIntent);
2383176b29a003f11fd934137871d574995319408665cristy      (void) ResetMagickMemory(&image->chromaticity,0,
2384176b29a003f11fd934137871d574995319408665cristy        sizeof(image->chromaticity));
2385176b29a003f11fd934137871d574995319408665cristy    }
238698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23902dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG width: %.20g, height: %.20g\n"
23912dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG color_type: %d, bit_depth: %d\n"
23922dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG compression_method: %d\n"
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
23942dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) ping_width, (double) ping_height,
23952dd1906783a5ece58a6105b4f59239e28b13caddglennrp        ping_color_type, ping_bit_depth,
23962dd1906783a5ece58a6105b4f59239e28b13caddglennrp        ping_compression_method,
2397faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
23982dd1906783a5ece58a6105b4f59239e28b13caddglennrp
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2401ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (png_get_valid(ping,ping_info, PNG_INFO_iCCP))
2402ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {
2403ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_iCCP=MagickTrue;
2404ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      if (logging != MagickFalse)
2405ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2406ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG iCCP chunk.");
2407ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    }
2408ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
240998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
241098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
241198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_gAMA=MagickTrue;
241298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
241398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
241498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG gAMA chunk.");
241598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
241698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
241798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
241898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
241998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_cHRM=MagickTrue;
242098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
242198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
242298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG cHRM chunk.");
242398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
242498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2425ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (ping_found_iCCP != MagickTrue && png_get_valid(ping,ping_info,
2426ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      PNG_INFO_sRGB))
242798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
2428ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_sRGB=MagickTrue;
242998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
243098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2431ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG sRGB chunk.");
243298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
243398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2434ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2435e604a757f40a91c286711c49577eeced17ea97adglennrp    if (ping_found_iCCP !=MagickTrue &&
2436ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_sRGB != MagickTrue &&
2437ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info, PNG_INFO_iCCP))
243898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
2439ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_iCCP=MagickTrue;
244098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
244198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2442ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG iCCP chunk.");
244398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
244498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2445faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2450e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2451e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2452e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2453e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2454e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2455e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2456e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2457e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
24660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
2475ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2476e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          profile=BlobToStringInfo(info,profile_length);
2477ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2478e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          if (profile == (StringInfo *) NULL)
2479ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          {
2480ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            png_warning(ping, "ICC profile is NULL");
2481ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            profile=DestroyStringInfo(profile);
2482ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          }
2483ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          else
2484ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          {
2485ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            if (ping_preserve_iCCP == MagickFalse)
2486edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2487ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 int
2488ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
2489ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
2490ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2491ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2492ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 png_uint_32
2493ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   length,
2494ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
2495ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2496ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 unsigned char
2497ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   *data;
2498ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2499ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
2500ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2501ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
2502ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 {
2503ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
2504ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   {
2505ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
2506ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
2507ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2508ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
2509ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                         (unsigned long) length);
2510ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2511ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
2512ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
2513ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2514ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2515ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
2516ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
2517ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
2518ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2519ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
2520ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
2521ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2522ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
2523ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
2524ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
2525ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        if (image->rendering_intent==UndefinedIntent)
2526ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
2527ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
2528ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
2529ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
2530ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
2531ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        break;
2532ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
2533ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   }
2534ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 }
2535ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
2536ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 {
2537ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2538ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
2539ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        (unsigned long) length);
2540ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) SetImageProfile(image,"icc",profile,exception);
2541ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 }
2542edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2543ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            else /* Preserve-iCCP */
2544edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2545ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) SetImageProfile(image,"icc",profile,exception);
2546edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2547ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2548ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            profile=DestroyStringInfo(profile);
2549ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          }
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2553ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2556ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    if (ping_found_iCCP==MagickFalse && png_get_valid(ping,ping_info,
2557ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        PNG_INFO_sRGB))
2558ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {
2559ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      if (png_get_sRGB(ping,ping_info,&intent))
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2561ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        if (image->rendering_intent == UndefinedIntent)
2562ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          image->rendering_intent=
2563ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             Magick_RenderingIntent_from_PNG_RenderingIntent (intent);
25640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2567e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2569ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    }
2570ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2571ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    else if (mng_info->have_global_srgb)
2572ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      {
2573ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        if (image->rendering_intent == UndefinedIntent)
2574ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          image->rendering_intent=
2575ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            Magick_RenderingIntent_from_PNG_RenderingIntent
2576ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            (mng_info->global_srgb_intent);
2577ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      }
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2580ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2581ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2583faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2584faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2585faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
25860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
259598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2596faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2597faa852bad40107edae19405e76a299057668d795glennrp    {
2598faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2599faa852bad40107edae19405e76a299057668d795glennrp        {
2600faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2601faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2602faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2603faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2604faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2605faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2606faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2607faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2608faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2609faa852bad40107edae19405e76a299057668d795glennrp        }
2610faa852bad40107edae19405e76a299057668d795glennrp    }
26110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2612faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
26230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2624ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp       ping_found_cHRM=MagickTrue;
2625ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
26263d627862fb79aad8a20be4f1587f0b8761db441aglennrp       if (image->chromaticity.red_primary.x>0.6399f &&
26273d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
26283d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
26293d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
26303d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
26313d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
26323d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
26333d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
26343d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
26353d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
26363d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
26373d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
26383d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
26393d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
26403d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
26413d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f)
26423d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_sRGB_cHRM=MagickTrue;
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2645e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26473d627862fb79aad8a20be4f1587f0b8761db441aglennrp      if (ping_found_sRGB != MagickTrue &&
26483d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_gAMA != MagickTrue ||
264984288238d90b2e1831857d6b2427abd7875b7e1bglennrp          (image->gamma > .45 && image->gamma < .46)) &&
26503d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_cHRM != MagickTrue ||
2651cd8b331760407523f2a59cc65c1cd9c3d4422bafcristy          ping_found_sRGB_cHRM != MagickFalse) &&
26523d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_iCCP != MagickTrue)
26535cf1bff142633838354b1080183c957900bc80e8glennrp      {
26545cf1bff142633838354b1080183c957900bc80e8glennrp         png_set_sRGB(ping,ping_info,
26555cf1bff142633838354b1080183c957900bc80e8glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent
26565cf1bff142633838354b1080183c957900bc80e8glennrp            (image->rendering_intent));
26575cf1bff142633838354b1080183c957900bc80e8glennrp         file_gamma=1.000f/2.200f;
26585cf1bff142633838354b1080183c957900bc80e8glennrp         ping_found_sRGB=MagickTrue;
265984288238d90b2e1831857d6b2427abd7875b7e1bglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2660918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp           "    Setting sRGB as if in input");
26615cf1bff142633838354b1080183c957900bc80e8glennrp      }
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26635cf1bff142633838354b1080183c957900bc80e8glennrp
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2665faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2667905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2668905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
26690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2673e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2674e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2678faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2679faa852bad40107edae19405e76a299057668d795glennrp    {
2680faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2681faa852bad40107edae19405e76a299057668d795glennrp        {
2682faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2683faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2684faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2685faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2686faa852bad40107edae19405e76a299057668d795glennrp        }
2687faa852bad40107edae19405e76a299057668d795glennrp    }
2688faa852bad40107edae19405e76a299057668d795glennrp
26895c97f62ba919c3c109f0072df3b560056565e9e7cristy  x_resolution=0;
26905c97f62ba919c3c109f0072df3b560056565e9e7cristy  y_resolution=0;
26915c97f62ba919c3c109f0072df3b560056565e9e7cristy  unit_type=0;
2692faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
26980881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
269916ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.x=(double) x_resolution;
270016ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.y=(double) y_resolution;
27010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
270516ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.x=(double) x_resolution/100.0;
270616ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.y=(double) y_resolution/100.0;
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2711e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2712e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2715823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2716faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
27220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2724faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
27300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2731faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2732edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              {
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
2735edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                    png_warning(ping,
2736edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                      "global tRNS has more entries than global PLTE");
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2738edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                else
2739edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  {
2740edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                     png_set_tRNS(ping,ping_info,mng_info->global_trns,
2741edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                       (int) mng_info->global_trns_length,NULL);
2742edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  }
2743edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               }
2744bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2749faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2758faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2759faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
27600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
27630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
27660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
27690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2770c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2771c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2772c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2778edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"No global PLTE in file");
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2782bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2783faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2784faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
27860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2787faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2789bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2790bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2791bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
27922dd1906783a5ece58a6105b4f59239e28b13caddglennrp      /* Set image background color.
27932dd1906783a5ece58a6105b4f59239e28b13caddglennrp       * Scale background components to 16-bit, then scale
2794bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2795bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
27962cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2797bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
27980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2799fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth == 1)
2800bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
28010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2802fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 2)
2803bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
28040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2805fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 4)
2806bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
28070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2808fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth <= 8)
2809bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
28102cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2811bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2812bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2813bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
28142cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2815bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2816bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
28172dd1906783a5ece58a6105b4f59239e28b13caddglennrp            if (logging != MagickFalse)
28182dd1906783a5ece58a6105b4f59239e28b13caddglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28192dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 "    Reading PNG bKGD chunk, raw ping_background=(%d,%d,%d).\n"
28202dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 "    bkgd_scale=%d.  ping_background=(%d,%d,%d).",
28212dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->red,ping_background->green,
28222dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->blue,
28232dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 bkgd_scale,ping_background->red,
28242dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->green,ping_background->blue);
2825bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
28262cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2827bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2828faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
28290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2830bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2831faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
28320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2833bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2834bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
28350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
283616ea139d53d867211d3bb0fa859a83de653f687ecristy        image->background_color.alpha=OpaqueAlpha;
28372cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2838bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2839bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2840bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2841bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2842bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2843bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2845bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2846a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2847faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2850a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
285535ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
285635ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
285735ef824baa82511126ff0072ae30eee0da9c05a3cristy
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2862fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      max_sample = (int) ((one << ping_file_depth) - 1);
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2864faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2865faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2866faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2867faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2868faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2869faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
28703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
28723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2875faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
28768a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          image->alpha_trait=UndefinedPixelTrait;
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2880a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
28819b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp            scale_to_short;
2882a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2883fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale_to_short = 65535L/((1UL << ping_file_depth)-1);
2884a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2885a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2886a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2887a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2888a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
288916ea139d53d867211d3bb0fa859a83de653f687ecristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
289005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2891faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28930f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
28940f111984738842d27d04aed2a3f823d82a943506glennrp              {
28950f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28962dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    Raw tRNS graylevel = %d, scaled graylevel = %d.",
28972dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (int) ping_trans_color->gray,(int) transparent_color.alpha);
28980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28990f111984738842d27d04aed2a3f823d82a943506glennrp              }
290016ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.red=transparent_color.alpha;
290116ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.green=transparent_color.alpha;
290216ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.blue=transparent_color.alpha;
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2909faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2914faa852bad40107edae19405e76a299057668d795glennrp
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2916faa852bad40107edae19405e76a299057668d795glennrp
2917faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2918faa852bad40107edae19405e76a299057668d795glennrp
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2923bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2925bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2928faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2929faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2940faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2941faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2942a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
294316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
294416ea139d53d867211d3bb0fa859a83de653f687ecristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
29458d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    {
29460a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      double
29470a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp        image_gamma = image->gamma;
29480a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp
29490a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      (void)LogMagickEvent(CoderEvent,GetMagickModule(),
29500a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp         "    image->gamma=%f",(float) image_gamma);
29510a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp
29520a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      if (image_gamma > 0.75)
29538d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        {
29540a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp          /* Set image->rendering_intent to Undefined,
2955e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp           * image->colorspace to GRAY, and reset image->chromaticity.
29568d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp           */
295767429939a9bdca8c2ea541cd690b8e479c921527glennrp          image->intensity = Rec709LuminancePixelIntensityMethod;
29588d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          SetImageColorspace(image,GRAYColorspace,exception);
29598d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        }
2960ccc36af759d30fb50b1deda241d038402a393b17glennrp      else
2961ccc36af759d30fb50b1deda241d038402a393b17glennrp        {
2962ccc36af759d30fb50b1deda241d038402a393b17glennrp          RenderingIntent
2963ccc36af759d30fb50b1deda241d038402a393b17glennrp            save_rendering_intent = image->rendering_intent;
2964ccc36af759d30fb50b1deda241d038402a393b17glennrp          ChromaticityInfo
2965ccc36af759d30fb50b1deda241d038402a393b17glennrp            save_chromaticity = image->chromaticity;
2966ccc36af759d30fb50b1deda241d038402a393b17glennrp
2967ccc36af759d30fb50b1deda241d038402a393b17glennrp          SetImageColorspace(image,GRAYColorspace,exception);
2968ccc36af759d30fb50b1deda241d038402a393b17glennrp          image->rendering_intent = save_rendering_intent;
2969ccc36af759d30fb50b1deda241d038402a393b17glennrp          image->chromaticity = save_chromaticity;
2970ccc36af759d30fb50b1deda241d038402a393b17glennrp        }
2971ccc36af759d30fb50b1deda241d038402a393b17glennrp
2972ccc36af759d30fb50b1deda241d038402a393b17glennrp      image->gamma = image_gamma;
29738d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    }
29746647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
2975e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp  (void)LogMagickEvent(CoderEvent,GetMagickModule(),
29760a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      "    image->colorspace=%d",(int) image->colorspace);
2977a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
2978faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
297932340ffa74550819f755f966e397ed58bbccd8e5glennrp      ((int) ping_bit_depth < 16 &&
298032340ffa74550819f755f966e397ed58bbccd8e5glennrp      (int) ping_color_type == PNG_COLOR_TYPE_GRAY))
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2982befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2983befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2984befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2986befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2987fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      image->colors=one << ping_file_depth;
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
299067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
299167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
299267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
299367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2995faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
3001bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
30020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
301416ea139d53d867211d3bb0fa859a83de653f687ecristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
3015edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
30160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3017faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
30230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30246af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30306af6cf1a950b111ad0ac706269a703086693ba71glennrp
303167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
30326af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
30336af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
30346af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
30356af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
30366af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30419b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp          Quantum
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
304426ac8585e46188a648abf5fa3a1a7d264d8b3cb9Cristy          scale = (Quantum) ((65535UL)/((1UL << ping_file_depth)-1));
30450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30469b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
30479b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp          scale = ScaleShortToQuantum(scale);
30489b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp#endif
30490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3050bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3058147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3059cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
3060cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
3061147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
3062151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        msg[MagickPathExtent];
3063147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3064fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     /* encode ping_width, ping_height, ping_file_depth, ping_color_type,
3065147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
3066147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3067151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy     (void) FormatLocaleString(msg,MagickPathExtent,
30687cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
30693398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.width,height",msg,exception);
3070147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3071151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy     (void) FormatLocaleString(msg,MagickPathExtent,"%d",(int) ping_file_depth);
30723398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.bit_depth",msg,exception);
3073147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3074151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy     (void) FormatLocaleString(msg,MagickPathExtent,"%d (%s)",
30755dff435eceea4f80207a906b11e65aed48fe3f27glennrp         (int) ping_color_type,
30765dff435eceea4f80207a906b11e65aed48fe3f27glennrp         Magick_ColorType_from_PNG_ColorType((int)ping_color_type));
30773398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.color_type",msg,exception);
3078147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3079913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (ping_interlace_method == 0)
3080913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3081151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%d (Not interlaced)",
3082913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3083913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3084913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else if (ping_interlace_method == 1)
3085913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3086151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%d (Adam7 method)",
3087913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3088913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3089913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else
3090913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3091151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%d (Unknown method)",
3092913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3093913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3094913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
3095913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp
3096913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (number_colors != 0)
3097913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3098151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%d",
3099913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) number_colors);
31003398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:PLTE.number_colors",msg,
3101913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            exception);
3102913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
310339d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp   }
3104fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
310539d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp   read_tIME_chunk(image,ping,ping_info,exception);
3106fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
310739d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
3108147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
31140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31150ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
3116347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
3117347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31191b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
31201b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
31211b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
31221b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3125e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3128edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3129868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3130cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3132edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
31360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
31430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3144a701bb35fa5f33c41f4053b39e0f4c4c20ec17d4Cristy  status=SetImageExtent(image,image->columns,image->rows,exception);
3145a701bb35fa5f33c41f4053b39e0f4c4c20ec17d4Cristy  if (status == MagickFalse)
3146a701bb35fa5f33c41f4053b39e0f4c4c20ec17d4Cristy    return(DestroyImageList(image));
3147a701bb35fa5f33c41f4053b39e0f4c4c20ec17d4Cristy
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
31490997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(image->rows,ping_rowbytes*
3150cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
31510997332e2c35a821b271d6e7473c01c10dc206adcristy  else
31520997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(ping_rowbytes,sizeof(*ping_pixels));
31530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31540997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
3155edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation failed");
31560997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
31570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31645f766ef8b0cd9906c2c3a56d845828380a251073cristy  quantum_info=AcquireQuantumInfo(image_info,image);
316516ea139d53d867211d3bb0fa859a83de653f687ecristy
316616ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
3167edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping,"Failed to allocate quantum_info");
31680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31694b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
31704b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp
3171c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
3172c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3173c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
3174c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
3175c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3176c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
3177c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3180c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
3181c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3182c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
3183c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
3184c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
3185ccc36af759d30fb50b1deda241d038402a393b17glennrp        image->alpha_trait=
3186ccc36af759d30fb50b1deda241d038402a393b17glennrp            (((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
3187c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
3188c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3189b0a657e13c4aefba39c51292005427b47277869dcristy            BlendPixelTrait : UndefinedPixelTrait;
31900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3191c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
3192c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
3193c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
3194c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
31950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3196c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
3197c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
31980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3199cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
3200c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3201c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          if (pass < num_passes-1)
3202c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp            continue;
3203c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3204862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
320616ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
3207c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
32080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320916ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
321016ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321116ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
32120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
321316ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
321416ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321516ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
32160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
321716ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
321816ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321916ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
32200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
322116ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
322216ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
322316ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
32240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
322516ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
322616ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
322716ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
32283faa9a3fb01696daaf976d595f492cb530bffb21glennrp
3229c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
3230c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3231c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
3232a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
3233a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3234a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
3235a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3236c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3237c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
32385aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
32395aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
324016ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
3241c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
3242a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3243a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3244a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
3245a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3246c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
3247c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
3248c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
32494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
32504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
325116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
325216ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
325316ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
325416ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
325516ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
325616ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
32574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
3258a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3259a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3260a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
32614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
32624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
32634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
326416ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
3265c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
3266c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
32670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3268af9320404a7b05014476f844b11110157a21b73eglennrp          if (num_passes == 1)
3269c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3270af9320404a7b05014476f844b11110157a21b73eglennrp              status=SetImageProgress(image,LoadImageTag,
3271af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) y, image->rows);
32720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3273c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
3274c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
3275c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
3276c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
3277c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
3278c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
32790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3280af9320404a7b05014476f844b11110157a21b73eglennrp        if (num_passes != 1)
32817a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3282c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
32837a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
32847a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
32857a287bfadeadea12e47c2376ca78a5d101687142cristy          }
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3290c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3302c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3303c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3304c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
330516ea139d53d867211d3bb0fa859a83de653f687ecristy
33068a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
3307b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
33080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
3310b0a657e13c4aefba39c51292005427b47277869dcristy        (image->alpha_trait  == BlendPixelTrait?  2 : 1)*
3311b0a657e13c4aefba39c51292005427b47277869dcristy        sizeof(*quantum_scanline));
33120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
3314edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
33150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3316bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33184f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        Quantum
33194f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp           alpha;
33204f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3322faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3323c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3326c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3327cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
3328c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3329c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp        if (pass < num_passes-1)
3330c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          continue;
3331c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
33324f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
33330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
333416ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
33360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3337cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3339c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3340faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33444f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
3345faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3346bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3348a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33494f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33504f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                alpha=ScaleCharToQuantum((unsigned char)*p++);
33514f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33524f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                SetPixelAlpha(image,alpha,q);
33534f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33544f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                if (alpha != OpaqueAlpha)
33550b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
33564f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
335716ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3361bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3362a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
336647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3370a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
33719b034ff476914bd7bcc87f5b23755b1e1512b64dglennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
337287281ec8d96ad26dfed9968c29b2920cb3d96744cristy              unsigned short
337358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
337458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
337558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3376c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
337758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
337858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3379c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
338058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
338158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3382c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
338358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
33840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3385faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3387c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3388c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3389c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3390c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3391c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3392c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
33934f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33944f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  alpha=ScaleShortToQuantum(quantum);
33954f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  SetPixelAlpha(image,alpha,q);
33964f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33974f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  if (alpha != OpaqueAlpha)
339858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
33994f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
340016ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
340158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
340258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
340358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
340458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
340558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
340647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
340758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
340858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
340916ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
34104f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
341116ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
34120b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
34134f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
341458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
341516ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3418a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
341947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
342247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
34263faa9a3fb01696daaf976d595f492cb530bffb21glennrp
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
34310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
343216ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
343316ea139d53d867211d3bb0fa859a83de653f687ecristy
343416ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
343516ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3436bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
343716ea139d53d867211d3bb0fa859a83de653f687ecristy        {
343816ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
343916ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
344016ea139d53d867211d3bb0fa859a83de653f687ecristy        }
34410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
34440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3445af9320404a7b05014476f844b11110157a21b73eglennrp        if (num_passes == 1)
34467a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3447cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
34489fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
344947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34507a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
34517a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
34527a287bfadeadea12e47c2376ca78a5d101687142cristy          }
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3454c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3455af9320404a7b05014476f844b11110157a21b73eglennrp      if (num_passes != 1)
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
345847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3462c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3465c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3466b0a657e13c4aefba39c51292005427b47277869dcristy    image->alpha_trait=found_transparent_pixel ? BlendPixelTrait :
3467b0a657e13c4aefba39c51292005427b47277869dcristy      UndefinedPixelTrait;
3468c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3470c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3471c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3473c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3474c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
34755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
34765aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34775aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3478bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
34795aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
34805aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3481c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3482c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3483c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
348416ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
348516ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
348616ea139d53d867211d3bb0fa859a83de653f687ecristy
34875c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
34885c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3489b0a657e13c4aefba39c51292005427b47277869dcristy      PixelTrait
3490b0a657e13c4aefba39c51292005427b47277869dcristy        alpha_trait;
34915c6f789db7a30bad01ace12b09ad9cd471339e94cristy
3492b0a657e13c4aefba39c51292005427b47277869dcristy      alpha_trait=image->alpha_trait;
34938a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
349416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3495b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait=alpha_trait;
34965c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
349747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34984eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3500ccc36af759d30fb50b1deda241d038402a393b17glennrp  if (logging != MagickFalse)
3501ccc36af759d30fb50b1deda241d038402a393b17glennrp  {
3502ccc36af759d30fb50b1deda241d038402a393b17glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3503ccc36af759d30fb50b1deda241d038402a393b17glennrp       "  image->storage_class=%d\n",(int) image->storage_class);
3504ccc36af759d30fb50b1deda241d038402a393b17glennrp  }
3505ccc36af759d30fb50b1deda241d038402a393b17glennrp
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
35100997332e2c35a821b271d6e7473c01c10dc206adcristy      pixel_info=RelinquishVirtualMemory(pixel_info);
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
351216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
3513868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3514cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
352147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3522faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
35318a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=BlendPixelTrait;
3532c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35333c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3534c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
35360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3538c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
35390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
35400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35418a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                 image->colormap[x].alpha_trait=BlendPixelTrait;
354216ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
354316ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
35440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3545c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
354647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
35480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
35490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
35500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
355216ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
35530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
35548a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->colormap[x].alpha_trait=BlendPixelTrait;
355516ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
35560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
35570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
35580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
355916ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
35600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
356147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3562a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3563a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3564a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
35650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
35660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
35680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
35690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
35700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3571c11cf6a442f3046940608a5743a68cc891deb13eglennrp
357216ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
35730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3574c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3576a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3577a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3578a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
35790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
35800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
358116ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
358216ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
358316ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
358416ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
358516ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
358616ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
35874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
358816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
35894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
35900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
359167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
35920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
35934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
359416ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
35954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3596a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
35970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
359816ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
35990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
36000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
36020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3603c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
36040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3605a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3606c11cf6a442f3046940608a5743a68cc891deb13eglennrp
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36093c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3610eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
36114eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
36124eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3613a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3614a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
36154eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3616a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3617a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36194eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
36204eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
36214eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
36224eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
36230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36244eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
36254eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36264eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
36270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36285285ae1de367013bf70a5a4e5feaefe3de8dda7bglennrp        if (strlen(text[i].key) > 16 &&
36296dfc26699a1aacdec9771115c4dcaf6c5c0a8f98glennrp            memcmp(text[i].key, "Raw profile type ",17) == 0)
36304eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
363199f968111025b4fadb966ca482c6f57750bf007bglennrp            const char
363299f968111025b4fadb966ca482c6f57750bf007bglennrp              *value;
363399f968111025b4fadb966ca482c6f57750bf007bglennrp
363499f968111025b4fadb966ca482c6f57750bf007bglennrp            value=GetImageOption(image_info,"profile:skip");
363599f968111025b4fadb966ca482c6f57750bf007bglennrp
363699f968111025b4fadb966ca482c6f57750bf007bglennrp            if (IsOptionMember(text[i].key+17,value) == MagickFalse)
363799f968111025b4fadb966ca482c6f57750bf007bglennrp            {
363899f968111025b4fadb966ca482c6f57750bf007bglennrp               (void) Magick_png_read_raw_profile(ping,image,image_info,text,
363999f968111025b4fadb966ca482c6f57750bf007bglennrp                  (int) i,exception);
364099f968111025b4fadb966ca482c6f57750bf007bglennrp               num_raw_profiles++;
364199f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
364299f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
364399f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Read raw profile %s",text[i].key+17);
364499f968111025b4fadb966ca482c6f57750bf007bglennrp            }
364599f968111025b4fadb966ca482c6f57750bf007bglennrp            else
364699f968111025b4fadb966ca482c6f57750bf007bglennrp            {
364799f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
364899f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
364999f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Skipping raw profile %s",text[i].key+17);
365099f968111025b4fadb966ca482c6f57750bf007bglennrp            }
36514eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
36524eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36534eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
36544eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
36554eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
36564eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
36574eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36584eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
3659151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            value=(char *) AcquireQuantumMemory(length+MagickPathExtent,
36604eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
36614eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
36624eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
3663edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"Memory allocation failed");
36644eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
36654eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
36664eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
36674eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
36684eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36694eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
36704eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
36714eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
36724eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
36734eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
36744eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
367516ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36774eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36794eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36802dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      length: %lu\n"
36812dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      Keyword: %s",
36822dd1906783a5ece58a6105b4f59239e28b13caddglennrp                (unsigned long) length,
36832dd1906783a5ece58a6105b4f59239e28b13caddglennrp                text[i].key);
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36864eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
368797f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
36884eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
3689fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    num_text_total += num_text;
3690fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
36913c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
370473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
37050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
371247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
3717edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp             png_error(ping,"Memory allocation failed");
37180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
3720edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping,"Cannot overwrite frozen MNG object buffer");
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
37290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
373116ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
37320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
37350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
3737edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping, "Cloning image for object buffer failed");
37380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3739faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
37410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3742faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3743faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3744faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3745faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3746faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3747faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3748faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3749faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
37500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3751faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
37613c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
376747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37730a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
37748a46d827a124555f0c48fb2368ec1bba8e079ab6cristy   /* Set image->alpha_trait to MagickTrue if the input colortype supports
37750a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
37760a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
37770a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
37788a46d827a124555f0c48fb2368ec1bba8e079ab6cristy    image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
37790a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
37800a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3781b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
37820a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3783224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#if 0  /* I'm not sure what's wrong here but it does not work. */
378417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy    if (image->alpha_trait != UndefinedPixelTrait)
37855830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37865830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3787def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,GrayscaleAlphaType,exception);
37885830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37895830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
3790def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,PaletteAlphaType,exception);
37915830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37925830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
3793def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,TrueColorAlphaType,exception);
37945830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
37955830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37965830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    else
37975830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37985830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
37995830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleType,exception);
38005830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
38015830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
38025830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteType,exception);
38035830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
38045830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
38055830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorType,exception);
38065830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
3807224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#endif
38085830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
3809cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3810cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3811cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3812151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy       msg[MagickPathExtent];
3813cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38144eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3815cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3816cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
3817151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
3818613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
38193398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:text",msg,
382016ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3821cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3822cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3823cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3824cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3825151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
3826cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
382716ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
382816ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3829cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3830cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
383198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_cHRM != MagickFalse)
38325961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
3833151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%s",
38345961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
38353398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:cHRM",msg,
383616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38375961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3838cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3839cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
38405961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
3841151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"%s",
38425961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
38433398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:bKGD",msg,
384416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38455961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
38465961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
3847151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy     (void) FormatLocaleString(msg,MagickPathExtent,"%s",
38485961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3849cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
385098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#if defined(PNG_iCCP_SUPPORTED)
385198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_iCCP != MagickFalse)
38523398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:iCCP",msg,
385316ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
385498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#endif
3855cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38564eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
38573398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:tRNS",msg,
385816ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38594eb3931feb349dd87142c78503b779228f3e1a0fglennrp
38604eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
386198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_sRGB != MagickFalse)
38624eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
3863151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
386498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            "intent=%d (%s)",
386598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            (int) intent,
386698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            Magick_RenderingIntentString_from_PNG_RenderingIntent(intent));
38673398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:sRGB",msg,
386898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp                 exception);
38694eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38704eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38714eb3931feb349dd87142c78503b779228f3e1a0fglennrp
387298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_gAMA != MagickFalse)
38734eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
3874151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
387516ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
387616ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
38773398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:gAMA",msg,
387816ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38794eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3880cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38814eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3882cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
38834eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
3884151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
388507523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
38864eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
38873398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:pHYs",msg,
388816ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38894eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38904eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3891cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38924eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
38934eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
38944eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
3895151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,"x_off=%.20g, y_off=%.20g",
38964eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
38973398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:oFFs",msg,
389816ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38994eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
39004eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
39014eb3931feb349dd87142c78503b779228f3e1a0fglennrp
3902fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
3903fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk     read_tIME_chunk(image,ping,end_info,exception);
3904fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
3905fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
390607523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
390707523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
390807523c7d2e40370804c2036295571e4b6426f94dglennrp       {
3909151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(msg,MagickPathExtent,
391007523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
391107523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
39123398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:vpAg",msg,
391316ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
391407523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3915cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3916cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39220997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
39270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3928868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3929edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
3930edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
3931edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3932edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* }  for navigation to beginning of SETJMP-protected block, revert to
3933edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    Throwing an Exception when an error occurs.
3934edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
3935edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
3944919429921a43880a338ed87e128d3b96219442efglennrp    *image;
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
394721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
394821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
3955151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    magic_number[MagickPathExtent];
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
3964e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
396547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
396947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
3971e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
3972fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
397316ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
397647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
397947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
398447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3985dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
398747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
399273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
399347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
399647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
400647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
40120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
401547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
401747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
40230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
402647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
402772715f5c299a6482f8eb175070b056d77b74a43fcristy  if ((IssRGBColorspace(image->colorspace) != MagickFalse) &&
40283d627862fb79aad8a20be4f1587f0b8761db441aglennrp      ((image->gamma < .45) || (image->gamma > .46)) &&
40293d627862fb79aad8a20be4f1587f0b8761db441aglennrp           !(image->chromaticity.red_primary.x>0.6399f &&
40303d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
40313d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
40323d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
40333d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
40343d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
40353d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
40363d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
40373d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
40383d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
40393d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
40403d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
40413d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
40423d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
40433d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
40443d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f))
4045ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4046ccc36af759d30fb50b1deda241d038402a393b17glennrp       SetImageColorspace(image,RGBColorspace,exception);
4047ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
404872715f5c299a6482f8eb175070b056d77b74a43fcristy
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
4050ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4051ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4052ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
4053ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.width,(double) image->page.height,
4054ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.x,(double) image->page.y);
4055ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4056ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  image->colorspace: %d", (int) image->colorspace);
4057ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
405897f90e23c85b9c58387880125c29d8c99126f83aglennrp
405997f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
40610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41134383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
41144383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
41154383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
4116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413616ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4139bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
414316ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
4151e0421fec74bee9a6f9def3d51aed4204f970ad73glennrp    reading_idat;
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4153bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
4167fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
41700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
417116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
41790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
418016ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
41810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
41840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
4198151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      type[MagickPathExtent];
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
42110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
42140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
4216151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) ConcatenateMagickString(type,"errr",MagickPathExtent);
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4222e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
4223e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
42266af512ae5eeeed8effd9af4d57aab7caf74c65eddirk      ThrowReaderException(CorruptImageError,"CorruptImage");
42270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
423047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42318fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
42340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4238bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
42400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
424347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4250bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
4251e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[2] << 8) | p[3]);
4252bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
4253e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[6] << 8) | p[7]);
4254e2440c250d94d64f8c70e596fe90808795aaa07ecristy            if ((jng_width == 0) || (jng_height == 0))
4255e2440c250d94d64f8c70e596fe90808795aaa07ecristy              ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
426047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
426347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
426847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42722dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_width:      %16lu,    jng_height:     %16lu\n"
42732dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_color_type: %16d,     jng_image_sample_depth: %3d\n"
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
42752dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (unsigned long) jng_width, (unsigned long) jng_height,
42762dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_color_type, jng_image_sample_depth,
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
427847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42802dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_image_interlace_method:  %3d"
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
42822dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_image_interlace_method,
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
428447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42862dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_compression_method:%3d\n"
42872dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_filter_method:     %3d\n"
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
42892dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_compression_method,
42902dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_filter_method,
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
429447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42958fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
429747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
431373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
431447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
431747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
431916ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
43200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
43270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
43310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
433873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
43390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
434416ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
43450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
43560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
43600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
43630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
43720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
43750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
437803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
439547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
440247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44038fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
440547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
441447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4416889a928b732161b6353bd880e5ea0802f184c6d4glennrp        if (alpha_image != NULL && image_info->ping == MagickFalse)
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4422bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
442403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44318fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
443947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4441889a928b732161b6353bd880e5ea0802f184c6d4glennrp        if (alpha_image != NULL && image_info->ping == MagickFalse)
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44508fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
44590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44608fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
44898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
44900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
45008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
45018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
45028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
45038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
45048182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
45058182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
45068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
450847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4517e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4518cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
4519da7803d6b1161960bc1e7db4d9718284c116fab8cristy            image->gamma=1.000f/2.200f;
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
452947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45385eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
45395eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
45400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
454747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45488fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
455816ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
455916ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
456316ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
456416ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4575fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
45768fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45838fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
45880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
461116ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4616325657913840de53be706fb11ec48ba11b53e808Cristy  if (color_image_info == (ImageInfo *) NULL)
4617325657913840de53be706fb11ec48ba11b53e808Cristy    {
4618325657913840de53be706fb11ec48ba11b53e808Cristy      assert(color_image == (Image *) NULL);
4619325657913840de53be706fb11ec48ba11b53e808Cristy      assert(alpha_image == (Image *) NULL);
4620325657913840de53be706fb11ec48ba11b53e808Cristy      return((Image *) NULL);
4621325657913840de53be706fb11ec48ba11b53e808Cristy    }
4622325657913840de53be706fb11ec48ba11b53e808Cristy
4623325657913840de53be706fb11ec48ba11b53e808Cristy  if (color_image == (Image *) NULL)
4624325657913840de53be706fb11ec48ba11b53e808Cristy    {
4625325657913840de53be706fb11ec48ba11b53e808Cristy      assert(alpha_image == (Image *) NULL);
4626325657913840de53be706fb11ec48ba11b53e808Cristy      return((Image *) NULL);
4627325657913840de53be706fb11ec48ba11b53e808Cristy    }
4628325657913840de53be706fb11ec48ba11b53e808Cristy
4629325657913840de53be706fb11ec48ba11b53e808Cristy  (void) SeekBlob(color_image,0,SEEK_SET);
4630325657913840de53be706fb11ec48ba11b53e808Cristy
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
46340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4635f0eec7524321f1be1bfe568a13ab7d4d0333c814cristy  assert(color_image_info != (ImageInfo *) NULL);
4636151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) FormatLocaleString(color_image_info->filename,MagickPathExtent,"%s",
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
46380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
46410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
46520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
46550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46568320f8b3b9670410e3e1b6f23f6de429d8f2102eCristy  status=SetImageExtent(image,image->columns,image->rows,exception);
46578320f8b3b9670410e3e1b6f23f6de429d8f2102eCristy  if (status == MagickFalse)
46588320f8b3b9670410e3e1b6f23f6de429d8f2102eCristy    return(DestroyImageList(image));
46598320f8b3b9670410e3e1b6f23f6de429d8f2102eCristy
4660bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
466216ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
466416ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
466516ea139d53d867211d3bb0fa859a83de653f687ecristy    {
466616ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
466716ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
466816ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
466916ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
467016ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
467116ea139d53d867211d3bb0fa859a83de653f687ecristy    }
467247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
46760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
46780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
468903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
46930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
46950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
469816ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4700151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         (void) FormatLocaleString(alpha_image_info->filename,MagickPathExtent,
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
47040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4706bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
470916ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
471147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
471217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy             if (image->alpha_trait != UndefinedPixelTrait)
471316ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
471416ea139d53d867211d3bb0fa859a83de653f687ecristy               {
471516ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
471616ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
471716ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
471816ea139d53d867211d3bb0fa859a83de653f687ecristy               }
47190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
472116ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
472316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
472416ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
47258a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->alpha_trait=BlendPixelTrait;
472616ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
472716ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
47290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
474147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
474247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
47500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
47520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
47530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
47560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
47580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
47620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
47690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
477044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp  if (status == MagickFalse)
477144c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp    return((Image *) NULL);
477244c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
47760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
48147ee973a2149db53911459cbf26f28eccdbc99efbglennrp    *image;
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
481721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
481821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
4825151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    magic_number[MagickPathExtent];
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
4834e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
4837e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
4838fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
483916ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
48420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
48450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
484947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
485047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
485247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48533b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
485647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
485747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
485973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
48600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
48630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
486447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
486547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
48720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
488247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
48940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
4902151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    page_geometry[MagickPathExtent];
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
4905889a928b732161b6353bd880e5ea0802f184c6d4glennrp    *image;
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49074383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
490821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
490921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
49104383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
493516ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4942bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4948bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4965bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
497438ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
497538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
497638ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
499947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
500047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
5002e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
5005e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
5006fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
500716ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
50100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
50130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
501747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
501847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
501947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
502073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
50210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
50240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
502547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
502647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
5034151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        magic_number[MagickPathExtent];
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
503647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
504047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
504147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5044bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
5045bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
504947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
5075151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      type[MagickPathExtent];
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
5086151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) ConcatenateMagickString(type,"errr",MagickPathExtent);
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5092e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
5093e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
509644c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp          {
509744c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp            status=MagickFalse;
509844c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp            break;
509944c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp          }
51000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
51030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
51060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51078fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
511047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
511347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5114bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
511647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
51260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
512816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
51300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
51370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
513916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
51410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
514647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
51510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51528fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
51580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5164f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy            if (length != 28)
5165f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy              {
5166f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy                if (chunk)
5167f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
5168f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy                ThrowReaderException(CorruptImageError,"CorruptImage");
5169f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy              }
5170f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy
5171bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
51730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
51760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5180e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5182e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
51868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
51870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
51900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
51940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
51970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5198f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy            p+=16;
5199f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy            simplicity=(size_t) mng_get_long(p);
52000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
52020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
52050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
52080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
521316ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
521547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
521616ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
52170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
52200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
52280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5229151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            (void) FormatLocaleString(page_geometry,MagickPathExtent,
5230e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
5231f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
52320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
5234bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
5236bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
52380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
52410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52518fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
52530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
52578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
52580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
52610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5269280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  "    repeat=%d,  final_delay=%.20g,  iterations=%.20g",
5270280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  repeat,(double) final_delay, (double) image->iterations);
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
527916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5283f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy            if (length < 2)
5284f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy              {
5285f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy                if (chunk)
5286f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
5287f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy                ThrowReaderException(CorruptImageError,"CorruptImage");
5288f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy              }
5289f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
52910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
529316ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
5300edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  Instead of using a warning we should allocate a larger
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
530316ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
531216ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
53200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
53230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
53300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
53310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
53330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
53340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5338280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      "  x_off[%d]: %.20g,  y_off[%d]: %.20g",
5339280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->x_off[object_id],
5340280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->y_off[object_id]);
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
53500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
53570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
53800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
53830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
539516ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
540647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
540947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
541047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
54160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5417bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
542435ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
54330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54348fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
54390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
544347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5448f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy            if (length > 0 && length < 257)
5449bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
545612560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5464bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54678182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
54740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
548147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
548247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
54868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
54878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
54898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
54918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
54938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
54958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
54978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
550247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
550647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55128fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5514e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5515cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
552047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
552447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5527fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55328fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
553447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
553747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
554116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
55440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
55470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
555147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55528fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
55550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
55590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
556247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
556347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
556547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5566bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
556847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
557047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5571bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
558247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
55868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
55870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55888182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
55898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
55900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5591bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5592bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
55930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
55960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5601e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
560347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5606bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5607bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
56080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5609bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5610bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
56110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5612bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5613bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
56140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56153a89fa4ae8254eda5e264fb9d6bfd97ea3022773glennrp                        if (change_timeout == 2)
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
56170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
56190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5622e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
562447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
56300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5634e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5635e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
563647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
56440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5645bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
56470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5648bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5656e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5657e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
56580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
566247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
566316ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
566516ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
566647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
567347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
56780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
56880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
56968a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                image->alpha_trait=UndefinedPixelTrait;
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
569816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
56990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5703e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5704e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5710a454cdcb00e5a619edb3eac3070b649569448e4aglennrp
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
5720a454cdcb00e5a619edb3eac3070b649569448e4aglennrp            if (length > 3)
5721a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              {
5722a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                first_object=(p[0] << 8) | p[1];
5723a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                last_object=(p[2] << 8) | p[3];
5724a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                p+=4;
572547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5726a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                for (i=(int) first_object; i <= (int) last_object; i++)
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5728a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  if (mng_info->exists[i] && !mng_info->frozen[i])
5729a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    {
5730a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      MngBox
5731a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                        box;
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5733a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      box=mng_info->object_clip[i];
5734a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      if ((p-chunk) < (ssize_t) (length-17))
5735a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                        mng_info->object_clip[i]=
5736a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                           mng_read_box(box,(char) p[0],&p[1]);
5737a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    }
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
573947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5740a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              }
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5744a454cdcb00e5a619edb3eac3070b649569448e4aglennrp
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57578fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
576547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
576647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5775bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5778f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy                for (j=1; j < (ssize_t) length; j+=2)
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5780f8d9cb8ed035c1b7df0bb5c73c40038d431eb39fCristy                  i=p[j-1] << 8 | p[j];
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57858fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
579047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
579747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
579847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5799a454cdcb00e5a619edb3eac3070b649569448e4aglennrp            if (length > 3)
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5801a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              first_object=(p[0] << 8) | p[1];
5802a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              last_object=(p[2] << 8) | p[3];
5803a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              p+=4;
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5805a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
5806a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              {
5807a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                if (mng_info->exists[i] && !mng_info->frozen[i] &&
5808a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    (p-chunk) < (ssize_t) (length-8))
5809a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  {
5810a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    MngPair
5811a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      new_pair;
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5813a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    MngPair
5814a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                      old_pair;
5815a454cdcb00e5a619edb3eac3070b649569448e4aglennrp
5816a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    old_pair.a=mng_info->x_off[i];
5817a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    old_pair.b=mng_info->y_off[i];
5818a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    new_pair=mng_read_pair(old_pair,(int) p[0],&p[1]);
5819a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    mng_info->x_off[i]=new_pair.a;
5820a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    mng_info->y_off[i]=new_pair.b;
5821a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  }
5822a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              }
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
582447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5831bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
583224e6d42307643613e0430bac65beddf8a43671bdglennrp            if (length > 4)
5833a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              {
5834a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                loop_level=chunk[0];
5835a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                mng_info->loop_active[loop_level]=1;  /* mark loop active */
583647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5837a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                /* Record starting point.  */
5838a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                loop_iters=mng_get_long(&chunk[1]);
58390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5840a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                if (logging != MagickFalse)
5841a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5842a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    "  LOOP level %.20g has %.20g iterations ",
5843a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    (double) loop_level, (double) loop_iters);
58440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5845a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                if (loop_iters == 0)
5846a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  skipping_loop=loop_level;
58470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5848a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                else
5849a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  {
5850a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    mng_info->loop_jump[loop_level]=TellBlob(image);
5851a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                    mng_info->loop_count[loop_level]=loop_iters;
5852a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                  }
58530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5854a454cdcb00e5a619edb3eac3070b649569448e4aglennrp                mng_info->loop_iteration[loop_level]=0;
5855a454cdcb00e5a619edb3eac3070b649569448e4aglennrp              }
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
585947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
586224e6d42307643613e0430bac65beddf8a43671bdglennrp            if (length > 0)
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
586424e6d42307643613e0430bac65beddf8a43671bdglennrp                loop_level=chunk[0];
586524e6d42307643613e0430bac65beddf8a43671bdglennrp
586624e6d42307643613e0430bac65beddf8a43671bdglennrp                if (skipping_loop > 0)
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
586824e6d42307643613e0430bac65beddf8a43671bdglennrp                    if (skipping_loop == loop_level)
586924e6d42307643613e0430bac65beddf8a43671bdglennrp                      {
587024e6d42307643613e0430bac65beddf8a43671bdglennrp                        /*
587124e6d42307643613e0430bac65beddf8a43671bdglennrp                          Found end of zero-iteration loop.
587224e6d42307643613e0430bac65beddf8a43671bdglennrp                        */
587324e6d42307643613e0430bac65beddf8a43671bdglennrp                        skipping_loop=(-1);
587424e6d42307643613e0430bac65beddf8a43671bdglennrp                        mng_info->loop_active[loop_level]=0;
587524e6d42307643613e0430bac65beddf8a43671bdglennrp                      }
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
587747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
587824e6d42307643613e0430bac65beddf8a43671bdglennrp                else
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
588024e6d42307643613e0430bac65beddf8a43671bdglennrp                    if (mng_info->loop_active[loop_level] == 1)
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
588224e6d42307643613e0430bac65beddf8a43671bdglennrp                        mng_info->loop_count[loop_level]--;
588324e6d42307643613e0430bac65beddf8a43671bdglennrp                        mng_info->loop_iteration[loop_level]++;
58840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
588524e6d42307643613e0430bac65beddf8a43671bdglennrp                        if (logging != MagickFalse)
588624e6d42307643613e0430bac65beddf8a43671bdglennrp                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
588724e6d42307643613e0430bac65beddf8a43671bdglennrp                          "  ENDL: LOOP level %.20g has %.20g remaining iters ",
588824e6d42307643613e0430bac65beddf8a43671bdglennrp                            (double) loop_level,(double)
588924e6d42307643613e0430bac65beddf8a43671bdglennrp                            mng_info->loop_count[loop_level]);
589047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
589124e6d42307643613e0430bac65beddf8a43671bdglennrp                        if (mng_info->loop_count[loop_level] != 0)
589224e6d42307643613e0430bac65beddf8a43671bdglennrp                          {
589324e6d42307643613e0430bac65beddf8a43671bdglennrp                            offset=
589424e6d42307643613e0430bac65beddf8a43671bdglennrp                              SeekBlob(image,mng_info->loop_jump[loop_level],
589524e6d42307643613e0430bac65beddf8a43671bdglennrp                              SEEK_SET);
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
589724e6d42307643613e0430bac65beddf8a43671bdglennrp                            if (offset < 0)
589824e6d42307643613e0430bac65beddf8a43671bdglennrp                              ThrowReaderException(CorruptImageError,
589924e6d42307643613e0430bac65beddf8a43671bdglennrp                                "ImproperImageHeader");
590024e6d42307643613e0430bac65beddf8a43671bdglennrp                          }
590124e6d42307643613e0430bac65beddf8a43671bdglennrp
590224e6d42307643613e0430bac65beddf8a43671bdglennrp                        else
590324e6d42307643613e0430bac65beddf8a43671bdglennrp                          {
590424e6d42307643613e0430bac65beddf8a43671bdglennrp                            short
590524e6d42307643613e0430bac65beddf8a43671bdglennrp                              last_level;
590624e6d42307643613e0430bac65beddf8a43671bdglennrp
590724e6d42307643613e0430bac65beddf8a43671bdglennrp                            /*
590824e6d42307643613e0430bac65beddf8a43671bdglennrp                              Finished loop.
590924e6d42307643613e0430bac65beddf8a43671bdglennrp                            */
591024e6d42307643613e0430bac65beddf8a43671bdglennrp                            mng_info->loop_active[loop_level]=0;
591124e6d42307643613e0430bac65beddf8a43671bdglennrp                            last_level=(-1);
591224e6d42307643613e0430bac65beddf8a43671bdglennrp                            for (i=0; i < loop_level; i++)
591324e6d42307643613e0430bac65beddf8a43671bdglennrp                              if (mng_info->loop_active[i] == 1)
591424e6d42307643613e0430bac65beddf8a43671bdglennrp                                last_level=(short) i;
591524e6d42307643613e0430bac65beddf8a43671bdglennrp                            loop_level=last_level;
591624e6d42307643613e0430bac65beddf8a43671bdglennrp                          }
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
592047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
592447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
592816ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
593147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
593447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
59510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
59540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
59570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
596416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
596847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
597447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
598047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
598347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
598947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
599247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
599847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
600147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
600747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
601047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
601647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
601947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
602547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
602847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
603447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
603847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
604216ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
604647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
606547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
606916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
607247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
607547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
607916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
608247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
608547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
609047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
61068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
61088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
611247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
611916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
612147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
612747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
612916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
613247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
6135bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
6137bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
614547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
614847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
615147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
615447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
615747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
616047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
616347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
617147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
617447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
617747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
618247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
61908fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
619247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
619947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
620247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
620847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
621647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62178182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
62188182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
6231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
6233bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
623516ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
624016ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
624147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
624847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
625247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
625947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
626247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
626347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
626447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
627316ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6276e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
6277e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
628816ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
629316ea139d53d867211d3bb0fa859a83de653f687ecristy              AcquireNextImage(image_info,image,exception);
629447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
630147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
63040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
63060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
63130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
631647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
63258a46d827a124555f0c48fb2368ec1bba8e079ab6cristy            image->alpha_trait=UndefinedPixelTrait;
632616ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
63270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6331e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6332e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
633647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
633716ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
634216ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
634347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
635047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
63560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
63590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
63680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
63770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
638347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
638747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
639247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6393bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
639447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
640547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6413889a928b732161b6353bd880e5ea0802f184c6d4glennrp        if (logging != MagickFalse)
6414889a928b732161b6353bd880e5ea0802f184c6d4glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6415889a928b732161b6353bd880e5ea0802f184c6d4glennrp            "exit ReadJNGImage() with error");
641647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
64200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
64280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
644947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
645247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
645447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
645547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
645747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64604e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
646147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
646447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
646747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
646947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
647047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
647247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
647647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
647947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
648147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
648247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
648447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64874e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
648847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
649147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
649447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
649647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
649747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
649947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
650916ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
651016ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
651116ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
651216ea139d53d867211d3bb0fa859a83de653f687ecristy
651316ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
651416ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
651516ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
651616ea139d53d867211d3bb0fa859a83de653f687ecristy
6517bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
652116ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
652516ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
652616ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
652847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
652947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
653347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
653416ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
653547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65513faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6559bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
656347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6564bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
656616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
656716ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
656816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
656916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
657016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
657116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
657216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
657316ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
657416ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
657647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
658517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                if (image->alpha_trait != UndefinedPixelTrait)
658616ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
658747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
659016ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
659116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
659247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
659547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
659847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
660147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6610e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
66134f7c434c6c7047588b48a5b71281f9ecf4c9d1accristy                length=(size_t) GetPixelChannels(image)*image->columns;
661416ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
661516ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
661647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
661716ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
661816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
662547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
662847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6629bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
663347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6634bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6635bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
663647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6637bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6638bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
663947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6640bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
664247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6644bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
664547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
664947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6650bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
665647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
665916ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6662bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
66669fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
666716ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
666816ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
666947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6670bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6672fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6681bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
668216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
668316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
668416ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
668516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
668616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
668716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
668816ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
669047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6694bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
669516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
669616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
669716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
669816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
669916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
670016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
670116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
670216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6703bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
670447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
670816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
670916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
671016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6711bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
671216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
671316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
671416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
671516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6716bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
671716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
671816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
671916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
672016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6721bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
672216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
672347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
672417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                              if (image->alpha_trait != UndefinedPixelTrait)
672516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
672616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
672716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6728bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
672916ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
673147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
673616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
673716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
673916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
674016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
674347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6748bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
674916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
675016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
675116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
675216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
675316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
675416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
675516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
675616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6757bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
675847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6760bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
676116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
676216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
676316ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
676416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
676516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
676616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
676716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6768bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
676947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
677216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
677316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
677416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6775bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
677616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
677916ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
678016ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
678116ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
678347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
678647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
678947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
679016ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
679116ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6808e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6810bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
681216ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
681616ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
681716ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
681847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6819bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6820bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
682216ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
68237c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6824bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6825bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
682647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6827bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6828bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
682947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6831bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
683247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6833bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
683547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6837bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
683847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
684416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
684516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
684616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
684716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
684947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6853bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
685416ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
685516ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
685616ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
685716ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6858bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
685947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
686016ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
686416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
686516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
686616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6867bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
686816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6869bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
687016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
687116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
687216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6873bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
687416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6875bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
687616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
687716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
687816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6879bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
688016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
688117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                              if (image->alpha_trait != UndefinedPixelTrait)
688216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
688316ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
688416ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6885bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
688616ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
688847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6893bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
689416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
689516ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6896bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6898bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
689916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
690016ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6901bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
690447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
69083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6909bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
691016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
691116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
691216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
691316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6914bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
691547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6917bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
691816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
691916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
692016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
692116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6922bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
692347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
692716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
692816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
692916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6930bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
693116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
693416ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
693616ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
693847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69423faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6948bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
695147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6952bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
695416ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
695516ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
695616ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
695716ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
695816ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
695916ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
696016ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
696116ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
696216ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
696447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
699847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
7014bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
7015bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
702147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
703347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
704416ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70562b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
70572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
705816ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
70592b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
70602b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
70612b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
70622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
70632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
70643faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7065cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
7066cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
7067cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
7068cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
7069cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
7070cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
707116ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
70728640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7074d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
7078bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7081d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
7085d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
708747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
708947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
709347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
71040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
710516ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
711016ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
711547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
711947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
71318a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
71320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
713416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
71350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
71400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
71430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
715147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
715216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
715547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
71600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
716547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
716616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
717147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
717947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
718016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
718447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
719047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
719116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
719347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
719647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
72040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
72070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
72100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
721547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
72210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
72230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7226e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
7227e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
72280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
723647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
723947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7241e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
724247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7247e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7259bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
726447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
726616ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
726747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
727047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
727347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
728247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
728547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
730247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
731247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
731547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7317e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
7318e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
731947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7321f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7322f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
732347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7324f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7325e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7326e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7327f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7328f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
732947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
733347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
733647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
733925c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
734447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
734747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
735047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
735525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7378bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7381bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
7384151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    version[MagickPathExtent];
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
739447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
740047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
740847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
7410151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) ConcatenateMagickString(version,"libpng ",MagickPathExtent);
7411151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MagickPathExtent);
741247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7415151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(version,",",MagickPathExtent);
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
7417151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            MagickPathExtent);
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
742047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
742106b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","MNG","Multiple-image Network Graphics");
742208e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags|=CoderSeekableStreamFlag;  /* To do: eliminate this. */
742347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
742847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
743047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
743347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7434afc97b1e31b78c973c4bf5e0be8d5090cfca8065glennrp  entry->mime_type=ConstantString("video/x-mng");
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
743806b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG","Portable Network Graphics");
743947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
744447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
744608e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7447d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
744847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
745147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
745506b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG8",
745606b627a07ff44e1ff93ef1288c9f428066ded10ddirk    "8-bit indexed with optional binary transparency");
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","PNG24",
746906b627a07ff44e1ff93ef1288c9f428066ded10ddirk    "opaque or binary transparent 24-bit RGB");
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
747147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
7473151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) ConcatenateMagickString(version,"zlib ",MagickPathExtent);
7474151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MagickPathExtent);
747547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7478151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(version,",",MagickPathExtent);
7479151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(version,zlib_version,MagickPathExtent);
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
748247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
748547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
749047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
749208e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7493d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
749606b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG32","opaque or transparent 32-bit RGBA");
749747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
75003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
750247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
750408e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7505d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
750806b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG48",
750906b627a07ff44e1ff93ef1288c9f428066ded10ddirk    "opaque or binary transparent 48-bit RGB");
7510fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7511fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7512fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7513fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7514fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7515fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7516fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
751708e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7518d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7519fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7520fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
752106b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG64","opaque or transparent 64-bit RGBA");
7522fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7523fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7524fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7525fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7526fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7527fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7528fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
752908e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7530d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7531fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7532fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
753306b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","PNG00",
7534698aab67f255491ec6bd984c9d0163990df57622glennrp    "PNG inheriting bit-depth, color-type from original, if possible");
75355830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
75365830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
75375830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
75385830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
75395830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#endif
75405830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
75415830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
754208e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
7543d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
75445830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) RegisterMagickInfo(entry);
75455830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
754606b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PNG","JNG","JPEG Network Graphics");
754747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
755447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
755608e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
75577fee329aec1090ff832c1b07fc4cc70c3b604f65glennrp  entry->mime_type=ConstantString("image/x-jng");
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
756047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7561868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
75623d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy  ping_semaphore=AcquireSemaphoreInfo();
756318b17443128598500357da7bff2f01683cf32890cristy#endif
756447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
7594fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG48");
7595fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG64");
75965830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) UnregisterMagickInfo("PNG00");
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
759847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7599868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
7600cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
76013d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy    RelinquishSemaphoreInfo(&ping_semaphore);
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
760625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
762516ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
762616ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
763416ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
76773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7684cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7691bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
77120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
77130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
77150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7716ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7717a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
7718a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7719a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
7720a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
7724ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7725a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping,
7726a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy      (png_alloc_size_t) allocated_length);
7727a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
7728a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7729a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
7730a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
7731a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
7734151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      "Raw profile type ",MagickPathExtent);
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77433b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7744f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
774647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7747bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
77533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
775447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
77593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
776147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
776447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
77673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7770cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
77714383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
77723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
77733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
77743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
77753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
77773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
77813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
77833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
778547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
778647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
778747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
77883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
778947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
77913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7793cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
77943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
779547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
779647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
779747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
779847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
779947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
780047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7801cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7802cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7803cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
780447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
780547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
780647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
780747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
780847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
780947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
781047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7811cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
781247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
78133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
781447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
78153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
78163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
781747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
78183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
78193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
78203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
782168a6b50ae30f5a551cd31d6e4b0c72990897a84fdirkstatic inline MagickBooleanType Magick_png_color_equal(const Image *image,
782268a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  const Quantum *p, const PixelInfo *q)
782368a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk{
782468a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  MagickRealType
782568a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk    value;
782668a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk
782768a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  value=(MagickRealType) p[image->channel_map[RedPixelChannel].offset];
782868a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  if (AbsolutePixelValue(value-q->red) >= MagickEpsilon)
782968a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk    return(MagickFalse);
783068a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  value=(MagickRealType) p[image->channel_map[GreenPixelChannel].offset];
783168a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  if (AbsolutePixelValue(value-q->green) >= MagickEpsilon)
783268a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk    return(MagickFalse);
783368a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  value=(MagickRealType) p[image->channel_map[BluePixelChannel].offset];
783468a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  if (AbsolutePixelValue(value-q->blue) >= MagickEpsilon)
783568a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk    return(MagickFalse);
783668a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk
783768a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk  return(MagickTrue);
783868a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk}
783968a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk
7840fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
7841fd6fd07e58e3d37313bec849313ac6e2b92e3957dirkstatic void write_tIME_chunk(Image *image,png_struct *ping,png_info *info,
7842fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  const char *date,ExceptionInfo *exception)
7843fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk{
7844fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  unsigned int
7845fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    day,
7846fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    hour,
7847fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    minute,
7848fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    month,
7849fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    second,
7850fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    year;
7851fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7852fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_time
7853fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ptime;
7854fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7855fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  time_t
7856fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ttime;
7857fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7858fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (date != (const char *) NULL)
7859fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
7860fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      if (sscanf(date,"%d-%d-%dT%d:%d:%dZ",&year,&month,&day,&hour,&minute,
7861fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          &second) != 6)
7862fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
7863fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
7864fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            "Invalid date format specified for png:tIME","`%s'",
7865fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            image->filename);
7866fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          return;
7867fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
7868fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.year=(png_uint_16) year;
7869fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.month=(png_byte) month;
7870fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.day=(png_byte) day;
7871fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.hour=(png_byte) hour;
7872fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.minute=(png_byte) minute;
7873fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.second=(png_byte) second;
7874fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
7875fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  else
7876fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  {
7877fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    time(&ttime);
7878fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    png_convert_from_time_t(&ptime,ttime);
7879fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
7880fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_set_tIME(ping,info,&ptime);
7881fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk}
7882fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
7883b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7884b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
788616ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
78873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
78880997332e2c35a821b271d6e7473c01c10dc206adcristy  char
78890997332e2c35a821b271d6e7473c01c10dc206adcristy    im_vers[32],
78900997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_runv[32],
78910997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_vers[32],
78920997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_runv[32],
78930997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_vers[32];
78940997332e2c35a821b271d6e7473c01c10dc206adcristy
789516ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
789616ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
789716ea139d53d867211d3bb0fa859a83de653f687ecristy
789816ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
789916ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
790016ea139d53d867211d3bb0fa859a83de653f687ecristy
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
79023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
79033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
79063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
79103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
79113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7914cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7915cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7916e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7917e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
79185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
791939992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
792039992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
79235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
79245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
79255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
79313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
79335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
79345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
79355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7936bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
794058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
794121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
794258e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
794358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7944da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7945fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7946d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
79478d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
794839992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7949991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7950918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_iCCP,
7951991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7952918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_sRGB,
7953991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
795426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
795526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
795626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7957a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7958e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
795926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
796026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
796126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
796226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
796326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
796426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
796526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7966fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_exclude_tIME,
7967e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
796826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
796926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
797026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
797126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
79728d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
7973ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_iCCP,
79740e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
79750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
797682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
79778ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7978d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7979d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79810997332e2c35a821b271d6e7473c01c10dc206adcristy  MemoryInfo
7982af1534a4abd2d6ef7f7e2833b95400301faff3d3cristy    *volatile pixel_info;
79830997332e2c35a821b271d6e7473c01c10dc206adcristy
79843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
79863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
798716ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
798816ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
798916ea139d53d867211d3bb0fa859a83de653f687ecristy
7990bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
79913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
79950997332e2c35a821b271d6e7473c01c10dc206adcristy    *ping_pixels;
7996d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
79975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7998f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
79990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
80005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
80015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
80025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
80035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
80045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
80055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
8006bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
80075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
80085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
80093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8010bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
80123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8015dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
8016fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
8017f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
80188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
80198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
80208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
8021dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
8022dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8023dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
8024dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
8025dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
8026dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
80273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
8028fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
803016ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
803116ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
803216ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
803316ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
8034b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
8035d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
8036d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
8037d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
8038d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
8039d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
8040151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         MagickLibVersionText,MagickPathExtent);
8041d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
8042151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy         MagickLibAddendum,MagickPathExtent);
8043ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
8044d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
8045d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
8046ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
8047ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
8048ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
8049ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
8050ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
8051d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
8052d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
8053ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
8054ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
8055ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
8056ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
8057ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
80588fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (logging != MagickFalse)
8059d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
8060d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    IM version     = %s",
8061d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           im_vers);
8062d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Libpng version = %s",
8063d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           libpng_vers);
8064ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(libpng_vers,libpng_runv) != 0)
8065ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8066ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8067ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           libpng_runv);
8068ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8069d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
8070d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           zlib_vers);
8071ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(zlib_vers,zlib_runv) != 0)
8072ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8073ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8074ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           zlib_runv);
8075ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8076d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
8077d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
80785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
80790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
80805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
80815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
80825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
80835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
80845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
80855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
80875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
80885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
80895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
80905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
80915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
80935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
80945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
80955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
80965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
8097dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
8098dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
8099dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
8100dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8101da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
8102f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp  ping_have_cheap_transparency=MagickFalse;
8103d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
81048d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
810539992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
8106991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
8107918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_iCCP=MagickFalse;
8108991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
8109918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_sRGB=MagickFalse;
8110991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
8111991d11dd9c33e65872778b81aff1347cd2878154glennrp
81120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
81130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
8114a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
8115dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
81160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
81170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
81180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
81190e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
81200e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
81210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
81220e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
8123fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  ping_exclude_tIME=mng_info->ping_exclude_tIME;
8124dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
81250e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
81260e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
81270e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
81280e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
81298d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
8130ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  ping_preserve_iCCP = mng_info->ping_preserve_iCCP;
81310e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
81320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
81330d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
81340d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
81350d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
81360d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
81370d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
8138ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8139ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * To do: recognize other variants of the sRGB profile, using the CRC to
8140ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * verify all recognized variants including the 7 already known.
8141ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8142ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Work around libpng16+ rejecting some "known invalid sRGB profiles".
8143ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8144ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Use something other than image->rendering_intent to record the fact
8145ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * that the sRGB profile was found.
8146ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8147ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Record the ICC version (currently v2 or v4) of the incoming sRGB ICC
8148ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * profile.  Record the Blackpoint Compensation, if any.
81490d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
8150ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   if (ping_exclude_sRGB == MagickFalse && ping_preserve_iCCP == MagickFalse)
81510d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
81520d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
81530d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
81540d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81550d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
81560d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
81570d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81580d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
81590d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
81600d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
81610d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
81620d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81630d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
81640d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
81650d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
8166ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                (LocaleCompare(name,"ICM") == 0))
8167ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
8168ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             {
8169ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
8170ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
8171ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
81720d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81730d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8174ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
8175ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
8176ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
817729a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8178ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
8179ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
81800d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8181ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
818229a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8183ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
818429a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
8185ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
8186ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
8187ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
8188ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
8189ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8190ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
8191ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
81920d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8193ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
8194ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
81950d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8196ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8197ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
8198ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
8199ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
8200ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
8201ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
8202ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
8203ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8204ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
8205ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
8206ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
8207ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
8208ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
8209ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
8210ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
8211ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
8212ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
8213ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_iCCP = MagickTrue;
8214ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_zCCP = MagickTrue;
8215ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_have_sRGB = MagickTrue;
8216ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
8217ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
821829a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
82190d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
8220ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
822129a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8222ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
822329a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
822429a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
82250d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
82260d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
82270d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
82280d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
82290d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
82308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
82318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
82328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
82338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8234fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
8235fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8236fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
8237fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8238f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=UndefinedClass");
8239fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
8240fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8241f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=DirectClass");
8242fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
8243fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8244f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=PseudoClass");
8245f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(), image->taint ?
8246cc96f2d3d09f91c9333d05e2e7216d4006f8a5eaglennrp          "    image->taint=MagickTrue":
8247cc96f2d3d09f91c9333d05e2e7216d4006f8a5eaglennrp          "    image->taint=MagickFalse");
8248fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
824928af3713c9111a471cc868c787760de89236fa3cglennrp
8250750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  if (image->storage_class == PseudoClass &&
82517e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
8252fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png48 || mng_info->write_png64 ||
8253fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     (mng_info->write_png_colortype != 1 &&
8254fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png_colortype != 5)))
82557e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
825616ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
82577e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
82587e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
82597e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
8260c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
826128af3713c9111a471cc868c787760de89236fa3cglennrp    {
8262c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
8263c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
8264c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
8265c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
8266c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8267c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
8268e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
8269c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
8270c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
827128af3713c9111a471cc868c787760de89236fa3cglennrp    }
8272bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8273c28acd632b7ea1724a54191d15db932f2e4d25e6glennrp  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
827416ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
82750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82763241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
82773241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
82783241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
82793241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
82803241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
828116ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
82823241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8283a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
8284a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
8285a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
8286a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
8287a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8288a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
8289a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8290a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
8291a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
8292a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
8293a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
82948e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
8295cd979955e4249aab3bdd79043718fa3b120239b8dirk  if (image->depth < 4)
829667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
829716ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
82988e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
82998e58efdecda887b08ef730d68290a61081ef2566glennrp
8300aac49630945ded4a68aca4f7c892e18b21afeba8dirk       if (image->depth > 2)
83018e58efdecda887b08ef730d68290a61081ef2566glennrp         {
83028e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
830391d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
83048e58efdecda887b08ef730d68290a61081ef2566glennrp
83058e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
83068e58efdecda887b08ef730d68290a61081ef2566glennrp           {
830716ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83088e58efdecda887b08ef730d68290a61081ef2566glennrp
830916ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
83108e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
83118e58efdecda887b08ef730d68290a61081ef2566glennrp
83128e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
83138e58efdecda887b08ef730d68290a61081ef2566glennrp             {
831416ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
831516ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
83168e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8317bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
83188e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
83198e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
83208e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83218e58efdecda887b08ef730d68290a61081ef2566glennrp
83228e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83238e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83243e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83258e58efdecda887b08ef730d68290a61081ef2566glennrp             {
832691d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
83278e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83288e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83298e58efdecda887b08ef730d68290a61081ef2566glennrp         }
83308e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
83318e58efdecda887b08ef730d68290a61081ef2566glennrp         {
83328e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
833391d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
83348e58efdecda887b08ef730d68290a61081ef2566glennrp
83358e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
83368e58efdecda887b08ef730d68290a61081ef2566glennrp           {
833716ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83388e58efdecda887b08ef730d68290a61081ef2566glennrp
833916ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
83408e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
83418e58efdecda887b08ef730d68290a61081ef2566glennrp
83428e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
83438e58efdecda887b08ef730d68290a61081ef2566glennrp             {
834416ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
834516ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
83468e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8347bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
83488e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
83498e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
83508e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83518e58efdecda887b08ef730d68290a61081ef2566glennrp
83528e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83538e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83543e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83558e58efdecda887b08ef730d68290a61081ef2566glennrp             {
835691d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
83578e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83588e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83598e58efdecda887b08ef730d68290a61081ef2566glennrp         }
83608e58efdecda887b08ef730d68290a61081ef2566glennrp       else
83618e58efdecda887b08ef730d68290a61081ef2566glennrp         {
83628e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
836391d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
83648e58efdecda887b08ef730d68290a61081ef2566glennrp
83658e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
83668e58efdecda887b08ef730d68290a61081ef2566glennrp           {
836716ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83688e58efdecda887b08ef730d68290a61081ef2566glennrp
836916ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
83708e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
83718e58efdecda887b08ef730d68290a61081ef2566glennrp
83728e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
83738e58efdecda887b08ef730d68290a61081ef2566glennrp             {
837416ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
837516ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
83768e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8377bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
83788e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
83798e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
83808e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83818e58efdecda887b08ef730d68290a61081ef2566glennrp
83828e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83838e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83843e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83858e58efdecda887b08ef730d68290a61081ef2566glennrp             {
838691d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
83878e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83888e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83898e58efdecda887b08ef730d68290a61081ef2566glennrp         }
8390cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
8391cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
839267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
839367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
839470e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
8395a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
83962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
83972b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
83982b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
83992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
84008e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
84012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
84022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
84032b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
84043faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
8405cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
8406cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
8407cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
8408cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
8409cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
8410cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
8411c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
841216ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
84138640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
84148640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
84158640fb5e9b1094f35f8beab436f81661b8a99448glennrp
8416d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  image_colors = (int) image->colors;
8417d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_opaque = (int) image->colors;
8418d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_transparent = 0;
8419d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_semitransparent = 0;
8420d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
8421197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  if (mng_info->write_png_colortype &&
8422a8036d6466b63ead629795b60772f160cca77c4cglennrp     (mng_info->write_png_colortype > 4 || (mng_info->write_png_depth >= 8 &&
8423a8036d6466b63ead629795b60772f160cca77c4cglennrp     mng_info->write_png_colortype < 4 &&
842417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     image->alpha_trait == UndefinedPixelTrait)))
8425a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8426a8036d6466b63ead629795b60772f160cca77c4cglennrp     /* Avoid the expensive BUILD_PALETTE operation if we're sure that we
8427a8036d6466b63ead629795b60772f160cca77c4cglennrp      * are not going to need the result.
8428a8036d6466b63ead629795b60772f160cca77c4cglennrp      */
8429a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (mng_info->write_png_colortype == 1 ||
8430a8036d6466b63ead629795b60772f160cca77c4cglennrp        mng_info->write_png_colortype == 5)
8431a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickFalse;
8432a8036d6466b63ead629795b60772f160cca77c4cglennrp
843317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     if (image->alpha_trait != UndefinedPixelTrait)
8434a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8435a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 2;
8436a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 1;
8437a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8438a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
8439a8036d6466b63ead629795b60772f160cca77c4cglennrp
8440eb5cb8dae42f21ec99df00cae387c3308aba18e6glennrp  if (mng_info->write_png_colortype < 7)
8441a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8442a8036d6466b63ead629795b60772f160cca77c4cglennrp  /* BUILD_PALETTE
8443a8036d6466b63ead629795b60772f160cca77c4cglennrp   *
8444a8036d6466b63ead629795b60772f160cca77c4cglennrp   * Normally we run this just once, but in the case of writing PNG8
8445e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
8446e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
84478ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
84488ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
84498ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
84508ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
8451c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
845282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
84538ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
845482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
8455d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
845682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
84578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
8458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
8459a8036d6466b63ead629795b60772f160cca77c4cglennrp    /*
8460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
8461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
8462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
8465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
8466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
84698a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     * If image->alpha_trait is MagickFalse, we ignore the alpha channel
8470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8473d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8474d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8478d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
84793c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
84828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
848316ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
84878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
848816ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
848916ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8490d6bf1617e99df0272b231855a933a74e99b6578fglennrp
849116ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
849216ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8493fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8494fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8495d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8499d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8500d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8502d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8504d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8505d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85068a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             "      image->alpha_trait=%.20g",(double) image->alpha_trait);
850703812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
85093c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8510fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
85117ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
85127ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8513d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
85148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
851516ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
85162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8517d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
85187ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8519d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8520d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8521d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8522d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8523d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8524d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
852516ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
85267ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
85272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8528d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8530d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8531d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8532d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8534d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8535d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8536d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8537d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
853816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8540d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8541d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
85422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
854583c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
854716ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
854816ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
85497ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
85508d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
85518d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85528d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
85547ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8555d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8556fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8557fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8558fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
85592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8561d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8562d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
85637ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
856416ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8565d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
856697fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8567d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8568d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
856917f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy           if (image->alpha_trait == UndefinedPixelTrait ||
857016ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
85718d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8572d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
85738d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8574d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
857616ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
857716ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8578d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8579d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8580d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8581d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8582d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
858368a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk                       if (Magick_png_color_equal(image,q,opaque+i))
8584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8585d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8586d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
858716ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8588d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8589d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
859016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
859116ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8592d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85938d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85948d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
859516ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
85968d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8597d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
85988d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8599d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8600d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
860116ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
860216ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
860316ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
860416ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
860516ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
860616ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
860716ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
860816ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
8609972d1c4895c4ee6da1b6745e1bb9cb71ee5d6d08cristy                         GetPixelGray(image,q);
8610d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8611d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8612d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8613d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8614d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
861568a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk                       if (Magick_png_color_equal(image,q,transparent+i))
8616d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8617d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8618d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8619d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8620d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8621d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8622d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
862316ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8624d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
86258d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
86268d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8627d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8628d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8629d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8630d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8631d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8632d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
863316ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8634d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8635d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
86368d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8637d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8638d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
863968a6b50ae30f5a551cd31d6e4b0c72990897a84fdirk                       if (Magick_png_color_equal(image,q,semitransparent+i)
864016ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
864116ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8642d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8643d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8644d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8645d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8646d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8647d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8648d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
864916ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8650d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8651d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
86528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
865316ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8654d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8655d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
86563c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
86574054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
86584054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8659d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8660d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8661d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8662d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8663c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8664c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8665c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8666c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8667c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8668c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8669c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8670c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8671d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8672d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8673ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8674ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8675ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8676ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8677d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8678d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
867903812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
86808e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8681c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8682388a8c871db8f82488f34c4f41fc64a58b8cfbf7glennrp               number_opaque++;
8683c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8684c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8685c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8686c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8687c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8688c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
868903812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8690a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8691a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8692a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8693d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8695d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
86963241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8697d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8698d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8699d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8700d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8701d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
87023241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8703d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8704d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8705d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8706d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
87073241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
87088d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
87098d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
87108d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8711fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8712d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8713d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
87140fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         ping_have_non_bw=MagickFalse;
87150fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
871645d4c34ce93ff377b9671844ffa1153b821061f6glennrp         if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
87170fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
871896bc620815234aaec28b928df51d1754cbe390dcglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
871996bc620815234aaec28b928df51d1754cbe390dcglennrp              "incompatible colorspace");
87207fb2652ba366fc984d1dbb0c66560b91c57dab78cristy           ping_have_color=MagickTrue;
872198b95773e388844e22c6e4006bb88396b33cf6b4glennrp           ping_have_non_bw=MagickTrue;
87220fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
87230fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
8724d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8725d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8726d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8727d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8728d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
87296185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
873016ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8731d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
87326185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8733e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8734e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8735e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
873616ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
873716ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8738e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8739e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8740e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8741e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8742e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
874316ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8744e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8745e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8746e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8747e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8748e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8749d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8750d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8751d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
87526185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8753d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8754d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8755d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8756d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
87576185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
875816ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
875916ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8760d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8761d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8762e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8763d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
876416ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8765d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8766e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8767d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8768bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8769bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
87704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8771d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8772d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
877316ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8774d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8775bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8776d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8777d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8778d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8779d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8780d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8781d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8782d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8783d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8784d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8785d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8786d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
87873241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8788d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8789d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
87903241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8791d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8792d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8793d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8794d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8795d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8796d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8797c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8798c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8799bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8800d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8801d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8802d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8803d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8804d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8805d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8806d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8807d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8808d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8809d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8810d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8811d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8812d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8813d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8814d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8815d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8816d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8817d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8818d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8819d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8820d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8821d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
88223241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8823d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8824d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8825d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8826d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8827d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8828d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8829d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
88306185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8831d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8832d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8833d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8834d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
88352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8836d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8837d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8838d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8839d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8840d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8841d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
884216ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8843d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
88443faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
88453faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8846d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8847d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8848d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8849d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8850d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8851d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8852d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8853d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8854d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8855bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8856d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8857d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8858d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8859d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8860fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8861fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8862d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8863d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
886416ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
88653c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
886616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8867d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
88683c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8869d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8870d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8871d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
887203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
887317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy                  if ((image->alpha_trait == UndefinedPixelTrait ||
887416ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
887516ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
887616ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
887716ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
88786185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
887916ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8880d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
88816185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
888203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
888316ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8884d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8885d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8886d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8887d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8888d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8889d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8890d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8891d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8892d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8893d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8894d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8895d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8896d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8897d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8898d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8899d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
890016ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
890183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8902d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8903d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
890472988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8905d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8906d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8907d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8908d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8909d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8910d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8911d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
891216ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8913d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
89146185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
89156185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
89163c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8917d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8918d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8919d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8920d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8921d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
89223c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8923d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8924d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
89253c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8926d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8927d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8928d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8929d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
893003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8931d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8932d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8933d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
89346185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8935d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8936d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8937d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8938d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
89396185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8940d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8941d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8942d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8943a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8944d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8945d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8946d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8947a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8948d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8949d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8950d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8951d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8952d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8953d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8954d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
89556185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
895603812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
895703812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8958d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
89593c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8960c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8961c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8962fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8963c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8964c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8965c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8966c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8967c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8968c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8969fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8970c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8971130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8972130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8973130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8974c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8975130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8976c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8977c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8978c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8979fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8980c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8981c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
898216ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8983fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
898416ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8985c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8986fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8987c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8988c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
898916ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
89908ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
899111a06d3f2cac0f17af7963e83bc6e9ebd2a377c0cristy                  SetPixelViaPixelInfo(image,&image->background_color,r);
899216ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
89938ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
89948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
899516ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
899616ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8997c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8998bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8999c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
9000c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
9001fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9002c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
9003c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
9004c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
900516ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
900616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
900716ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
9008c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
9009c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
9010c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
9011c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
9012c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
9013e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
9014e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
9015e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
9016c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
9017d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
9018d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
9019d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
9020d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9021d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
9022d337164012450d70d62e71cf4a308a29004f7d57glennrp
9023d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
9024d337164012450d70d62e71cf4a308a29004f7d57glennrp
902591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
9026d337164012450d70d62e71cf4a308a29004f7d57glennrp
9027d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
9028d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9029d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
9030d337164012450d70d62e71cf4a308a29004f7d57glennrp
9031d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
9032d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
9033d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
9034d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
903516ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
9036d337164012450d70d62e71cf4a308a29004f7d57glennrp
903716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
9038d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
9039d337164012450d70d62e71cf4a308a29004f7d57glennrp
9040d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
9041d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
904216ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
904354cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
904416ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
9045d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
9046bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9047d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
9048d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
9049d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
9050d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9051d337164012450d70d62e71cf4a308a29004f7d57glennrp
9052d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
9053d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
9054d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
9055d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
9056d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9057d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
90588e58efdecda887b08ef730d68290a61081ef2566glennrp
9059d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
9060d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
906191d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
9062d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
9063d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9064d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
9065d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
9066d337164012450d70d62e71cf4a308a29004f7d57glennrp
906782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
906882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
906982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
907082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
907182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
907282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
907382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
907482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
907591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
907682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
907782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
907882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9079e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
908082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
908182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
908282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
908382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
908482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
908516ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
908682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
908716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
908882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
908982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
909082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
909182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
909216ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
909316ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
909416ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
909582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
9096bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
909782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
909882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
909982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
910082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
910182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
910282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
910382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
910482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
910582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
910682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9107e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
910882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
910982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
911091d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
911182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
9112d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9113d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
911482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
9115c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
91168ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
9117c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
9118c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9119c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9120c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
9121c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
91228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
91238ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91243faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
91253faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
91263faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
91273faa9a3fb01696daaf976d595f492cb530bffb21glennrp
912891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
9129fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9130c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9131c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9132e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
9133fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9134c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
9135c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9136c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
9137c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
913816ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
91398d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
914016ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
9141c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
9142c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
9143c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
9144c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
914516ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
914654cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
914716ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
9148c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
9149bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9150c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
9151c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
9152c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9153c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
9154c722dd852e8abe407c2846d39662f7ade9c234deglennrp
9155c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
9156c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
9157c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9158c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
9159c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9160e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
9161c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
9162c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
916391d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
9164c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9165c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
9166c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
9167c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
91688ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91698ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
91708ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
917134ef720923a27004960cbcf4d75a8075445e85d7glennrp      /* Take care of special case with 256 opaque colors + 1 transparent
91728ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
91738ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
91748ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
91758ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
917634ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
917734ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
917834ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red background colors to 3-3-2-1");
917934ef720923a27004960cbcf4d75a8075445e85d7glennrp
91808ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
91818ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
91828ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
91838ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91848ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
91858ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
9186bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
918734ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
918834ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
918934ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red pixel colors to 3-3-2-1");
919034ef720923a27004960cbcf4d75a8075445e85d7glennrp
91918ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
91928ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91938ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
91948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
919516ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
9196bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
919716ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
91988ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
9199bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
92008ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
92018ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
920216ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
920316ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
920416ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
920516ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
92068ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
920716ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
92088ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
920916ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
92108ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
9211bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
92128ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
92138ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
9214bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
92158ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
92168ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
92178ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
92188ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
92198ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
92208ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
92218ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
92228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
92238ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
92248ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
92258ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
92268ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
92278ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
92288ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
92298ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
92308ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
9231fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
9232a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
9233fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
9234fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9235fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
9236fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
9237fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
9238fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
92390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
92400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
92410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
9242d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
92430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
92450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
92460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
92480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
92490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92508d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
9251d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
92520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
92530b206f5daa453dc1035db5890cabc899736dc2d0glennrp
92540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
92550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
9256fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
9257fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
9258fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
92595a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
92605a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
92615a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
9262fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
92635a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
92645a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
9265fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
9266fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
9267fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9268fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
9269fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
9270fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9271fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
9272fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
9273fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
927416ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
9275fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
9276fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9277fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
9278fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
9279fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
9280fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
928116ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
9282fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
9283fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9284fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
9285fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
928616ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
928716ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
928816ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
928916ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
929016ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
929116ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
929216ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
9293fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
9294fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
9295fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
9296fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
9297fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
929816ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
9299fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
9300bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9301fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
9302fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
9303fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
9304fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9305fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
9306fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
930767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
930867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
930967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
9310fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
931167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
931267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
931367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
931467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
9315fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
931667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
931767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
9318fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
9319fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9320bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9321fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
9322fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
9323fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
9324fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9325fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
9326fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9327fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
9328fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9329fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
9330fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9331fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
9332fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
9333fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
9334fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
93353c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
93363c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
93373c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
93383c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
9339f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
934017f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  image_matte=image->alpha_trait != UndefinedPixelTrait ? MagickTrue : MagickFalse;
934183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
934248c20621d4ce02a3833b107f710843d1e524d559glennrp  if (mng_info->write_png_colortype < 5)
9343197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette=image->storage_class == PseudoClass &&
9344197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      image_colors <= 256 && image->colormap != NULL;
9345197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  else
9346197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette = MagickFalse;
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
934852a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
934952a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
935052a479ca718756af72f96e127f8256499ab68f76glennrp    {
935116ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
935216ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
935316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
935415e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
935516ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
935652a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
935752a479ca718756af72f96e127f8256499ab68f76glennrp    }
935852a479ca718756af72f96e127f8256499ab68f76glennrp
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
936316ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
936416ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
93653e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
9366cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
9367cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
93680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
93703e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
9371cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
93720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
93780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
93860997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=(MemoryInfo *) NULL;
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
9398868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9399cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9401edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
94020997332e2c35a821b271d6e7473c01c10dc206adcristy      if (pixel_info != (MemoryInfo *) NULL)
94030997332e2c35a821b271d6e7473c01c10dc206adcristy        pixel_info=RelinquishVirtualMemory(pixel_info);
9404edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9405edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (quantum_info != (QuantumInfo *) NULL)
9406edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        quantum_info=DestroyQuantumInfo(quantum_info);
9407edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
940816ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
940916ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
941016ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
941116ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9414edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9415edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
9416edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
9417edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
9418edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
9419edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9420868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9421edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
9422edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
9423edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9424943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
9425a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
9426a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
9427a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
9428a3a5f956194e91458e2789966ad15308e8f3df47glennrp
9429f9eb20453e3475d44a3833f64c4a662c0106c43edirk#ifdef PNG_SET_USER_LIMITS_SUPPORTED
9430f9eb20453e3475d44a3833f64c4a662c0106c43edirk  /* Reject images with too many rows or columns */
9431f9eb20453e3475d44a3833f64c4a662c0106c43edirk  png_set_user_limits(ping,
9432f9eb20453e3475d44a3833f64c4a662c0106c43edirk    (png_uint_32) MagickMin(0x7fffffffL,
9433f9eb20453e3475d44a3833f64c4a662c0106c43edirk        GetMagickResourceLimit(WidthResource)),
9434f9eb20453e3475d44a3833f64c4a662c0106c43edirk    (png_uint_32) MagickMin(0x7fffffffL,
9435f9eb20453e3475d44a3833f64c4a662c0106c43edirk        GetMagickResourceLimit(HeightResource)));
9436f9eb20453e3475d44a3833f64c4a662c0106c43edirk#endif /* PNG_SET_USER_LIMITS_SUPPORTED */
9437f9eb20453e3475d44a3833f64c4a662c0106c43edirk
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94419bf97b6c2143eb20c330346b01e82102cc082725glennrp
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
944425024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  {
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
944625024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
944725024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     /* Disable new libpng-1.5.10 feature when writing a MNG because
944825024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      * zero-length PLTE is OK
944925024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      */
945025024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     png_set_check_for_invalid_index (ping, 0);
945125024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# endif
945225024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  }
94532b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
94582b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94612b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
94632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94644e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
94654e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
94662b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9470fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48 || mng_info->write_png64)
9471fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     image_depth=16;
9472fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
94750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
94790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
94850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9489e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9491e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94938a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        "    image_matte=%.20g",(double) image->alpha_trait);
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94958640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
94963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94978640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94998640fb5e9b1094f35f8beab436f81661b8a99448glennrp
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
95015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
9502dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
950326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
950526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
950626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
950716ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
9511dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9512dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
95153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9516dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
9517823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
951816ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
9519823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
952016ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
95213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9522dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
95233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9525dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
952616ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
952716ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9529991d11dd9c33e65872778b81aff1347cd2878154glennrp
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9532dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
953316ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
953416ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
95353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9536991d11dd9c33e65872778b81aff1347cd2878154glennrp
9537823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9538823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9539823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9540823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9541823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9542991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
954426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9546a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
954726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
954826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9549a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9551a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9552a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9553a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9554a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9555a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9556a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
95570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9558a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9559a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
95600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9561a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9562a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
95630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9564a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9565a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
95660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9567a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9568a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
95690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9570a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9571a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
95720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9573a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9574a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9575c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9576c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
95770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
95780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
95803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
95813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9583c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9584c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9585c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
95863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
95873b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95883b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
95893b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
95900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
959226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
95933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
95953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
95963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
95973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
95983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
95990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96001273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9602fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
96030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
96040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
96068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
96078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
96080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
96100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
96110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
96120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
96130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
96150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9617f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
96180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
96200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
96210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
96220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
96230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
96240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
96250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
962667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
96270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
962867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
962967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
963067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
96310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
96342b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
96358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
96368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
96378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
96385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
963958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
96408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
96410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
96420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
96430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
96440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
96458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
96488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
96490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96512cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
96528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
96530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
96550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
96560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
96598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
96600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96611273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
96624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
96631273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
96641273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
96651273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
96661273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
96674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
96684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
96694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
96700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9672c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9673c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9674c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9675c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9676c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9677c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9678c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
96794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
96810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9682fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png_colortype == 1)
9683fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
9684fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image_matte=MagickFalse;
9685fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
9686fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
9687fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
9688fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png24 || mng_info->write_png48 ||
9689fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 3)
96903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
96925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9695fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png32 || mng_info->write_png64 ||
9696fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 7)
96973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
96995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
97033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
97050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
97073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
97090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
97115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
97123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
97132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
97158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
97167c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
97177c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
97187c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97197c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
97203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97227c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
97233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97263c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
97270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9728d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
97298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
97300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9731d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
97335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
97343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
97360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9737def23e5d7331b1a13ed593b6d6aca516da382328cristy          if (image_info->type == TrueColorAlphaType)
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
97395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
97420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
9744def23e5d7331b1a13ed593b6d6aca516da382328cristy              image_info->type == PaletteAlphaType)
97455aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
97465aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
97477c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
9748261f64eea2c3a5a9586da65af2c59d2a39b05de0glennrp             image_info->type == UndefinedType)
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
97505aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
97518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
97525aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
97535aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97545aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
97555aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
97565aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97580b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
97595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97605aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
97615aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
97625aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
97645aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
97655aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
97665aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
97675aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97685aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
97695aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
97705aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
97720b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
97735aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
97755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
97765aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97775aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
97780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
97795aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
97803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
978326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97848640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
978526c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
97865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
97870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
97880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
97890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
97900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
97910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
97920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
97933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9794d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9795d6bf1617e99df0272b231855a933a74e99b6578fglennrp
97965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
979817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy          if (image->alpha_trait == UndefinedPixelTrait && ping_have_non_bw == MagickFalse)
97998d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
98003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98018640fb5e9b1094f35f8beab436f81661b8a99448glennrp
98025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
98033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
980435ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
98055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
98060f111984738842d27d04aed2a3f823d82a943506glennrp
98070f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
98080f111984738842d27d04aed2a3f823d82a943506glennrp           {
98090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9810edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"image has 0 colors");
98110f111984738842d27d04aed2a3f823d82a943506glennrp           }
98120f111984738842d27d04aed2a3f823d82a943506glennrp
981335ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
98145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9815d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9817d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9818d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9819d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9820d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
98210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9822d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9823d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9824d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
98250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9826d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9827d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
98305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
98312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98351a56e9c9268976936eeab9fe97eb664b847e444cglennrp        "    Tentative PNG color type: %s (%.20g)",
98361a56e9c9268976936eeab9fe97eb664b847e444cglennrp        PngColorTypeToString(ping_color_type),
98371a56e9c9268976936eeab9fe97eb664b847e444cglennrp        (double) ping_color_type);
98380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9840e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
98410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9843e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
98440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98463c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
98478640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
98488640fb5e9b1094f35f8beab436f81661b8a99448glennrp
98498640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9850e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
985358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
98564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
98577c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
98587c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
98597c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
98602b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98617c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
98627c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
98637c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
98642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
98664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
98694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
98714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
98724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9873a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
98744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
98757c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
98767c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98777c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
98784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
98814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9883bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
98860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
98884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
98890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
98914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
98920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
98944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
98950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
98974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
98980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
99004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
99010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
99034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
99040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
99064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
99070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
990911a06d3f2cac0f17af7963e83bc6e9ebd2a377c0cristy                (ScaleQuantumToShort(GetPixelInfoIntensity(image,
99104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
99110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
99130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
99154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
99160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
99184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
99194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9920fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9921fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9922fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9923fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9924fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
99254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
99262b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
99284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
99297c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
99307c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
99310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
99334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
99344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
99354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
99364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
99374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
99384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
99394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
99404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
99414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
99424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
99455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
99465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
99475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
99485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99528640fb5e9b1094f35f8beab436f81661b8a99448glennrp
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
99540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99552e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
99570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
995839992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
99608d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
99618d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
996335ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
99640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
99669c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
99670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99687c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
99714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
99734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
99744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
99754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
99764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
99784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
99794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
99804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
99850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9986136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9987d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9988f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
99890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
99915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
99920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
99965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
99993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
100005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
100010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1000235ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
10003bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
100045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
100053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
100063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100072b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
100080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
100090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
100113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
100123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
100131a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
100143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
100153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10019bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
100203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
100253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
100283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
100293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
100304bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
100323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
100332b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
100343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
100359c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
100360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
100389c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
100390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
100419c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
100423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100442b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
100455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
100490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
100513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1005217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
1005317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
100595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
100600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100613d627862fb79aad8a20be4f1587f0b8761db441aglennrp            if (!(mng_info->have_write_global_plte && matte == MagickFalse))
100623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10063bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
100690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100703b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
100713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1007298156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
10073f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
100740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1007539992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
100763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
10079d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10081befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
10082befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
10083befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
100845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
10085befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
100860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1008716ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
100885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
100920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1009358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
100940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
100950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
10096d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
10097d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
100980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10100d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
10101d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
101023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
101040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
101050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10106d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
101070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
10108c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
10109c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
10110c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10111c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
10112c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
10113d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
10114d6bf1617e99df0272b231855a933a74e99b6578fglennrp
10115d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
10116d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
10117750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp                       ping_trans_alpha[i]= (png_byte)
1011816ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
10119d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
101200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
101210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
101223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
101240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
101263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10127c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
101283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
101300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
101334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
101344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
101354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
101374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
101384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
101394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
101404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
101414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
101425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
101435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
101445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
101455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
101464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
101474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
101484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
101494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
101514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
101524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
101534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
101544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
101553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
101573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101584383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
101594383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
101602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
101613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
101623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
101633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
101645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
101653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
101663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
101673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1017035ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
1017135ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
1017235ef824baa82511126ff0072ae30eee0da9c05a3cristy
1017322ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
1017626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1017816ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
1017911a06d3f2cac0f17af7963e83bc6e9ebd2a377c0cristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(image,
1018016ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
1018116ea139d53d867211d3bb0fa859a83de653f687ecristy
101823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
101838f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1018416ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
1018516ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1018616ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
1018716ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
101883b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
10189991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
1019026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
101913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101923e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101933e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101943e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
101953e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
101963e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101979be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
101983e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
101993e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
102003e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
102013e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102023e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
102033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1020417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1020526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1020626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
102071273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
1020817a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
1020917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
1021017a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
1021117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
1021217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1021317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
1021417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10215a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
10216a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
1021717a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
1021817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1021917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
1022017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
102213b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
102220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
102230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
102250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
10226a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1022713d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
10228a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
102290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
102303b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
102313b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
102320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
102330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
102350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
102360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
102370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
102380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
10239a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
1024017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10241d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
102423c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
102433b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
102443b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102453b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
102463c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
102473c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
1024817a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
1024926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1025017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
102513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102531a56e9c9268976936eeab9fe97eb664b847e444cglennrp      "    PNG color type: %s (%d)", PngColorTypeToString(ping_color_type),
102541a56e9c9268976936eeab9fe97eb664b847e444cglennrp      ping_color_type);
102553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
102563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
102573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
102583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
102600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
102620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
102650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
102660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
102680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
102720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102734054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
102744054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
1027510d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
1027610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1027710d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
1027810d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
1027910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1028010d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
1028110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10282ef804f5802b3d6517d516556b64fccc5843710b6glennrp        0 or omitted: Use Z_HUFFMAN_ONLY strategy with the
1028310d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
1028410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1028510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
1028610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1028710d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
1028810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1028910d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
1029010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1029110d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
1029210d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
1029310d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
10294750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
1029510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
1029610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1029710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
1029885dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             a MNG, otherwise "none".  Did not work in IM-6.7.0-9
1029910d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
1030010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1030185dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp        8:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), adaptive
1030285dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             filtering. Unused prior to IM-6.7.0-10, was same as 6
1030310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10304ef804f5802b3d6517d516556b64fccc5843710b6glennrp        9:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), no PNG filters
103051868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
1030610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1030710d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
1030810d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
1030916ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
1031016ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
1031110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1031210d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
1031310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1031429dd80efe8d7489d5f689a8a723454e684f92a8fdirk  quality=image_info->quality == UndefinedCompressionQuality ? 75UL :
1031529dd80efe8d7489d5f689a8a723454e684f92a8fdirk     image_info->quality;
103160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103171868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
103181868258559ddf946fa73ef72dd43507b32623705glennrp    {
103191868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
103201868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
103211868258559ddf946fa73ef72dd43507b32623705glennrp    }
10322750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
103231868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
103243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
103263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10328bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
103290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103301868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
103311868258559ddf946fa73ef72dd43507b32623705glennrp    }
103320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103331868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
103341868258559ddf946fa73ef72dd43507b32623705glennrp    {
103351868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
10336a24b245fac14ef0617d691de0942697f2eb31b05glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
10337a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy=Z_RLE+1;
10338a24b245fac14ef0617d691de0942697f2eb31b05glennrp#else
10339a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
10340a24b245fac14ef0617d691de0942697f2eb31b05glennrp#endif
103413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103431868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
103441868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
103451868258559ddf946fa73ef72dd43507b32623705glennrp
103461868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
103473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103481868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
103493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103501868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
103511868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
103520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103531868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
103541868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103551868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
103561868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
103570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103581868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103591868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
103603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103614054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
1036210d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103631868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
103644054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
103654054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
103661868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103671868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
103681868258559ddf946fa73ef72dd43507b32623705glennrp        else
103691868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103701868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
103711868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
103723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103741868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
103751868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
103760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103771868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
103781868258559ddf946fa73ef72dd43507b32623705glennrp    {
103791868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
103801868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
103811868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
103821868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103831868258559ddf946fa73ef72dd43507b32623705glennrp      else
103841868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
103851868258559ddf946fa73ef72dd43507b32623705glennrp     }
103864054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
103871868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
103881868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
1038910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
103901868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
103911868258559ddf946fa73ef72dd43507b32623705glennrp    {
103921868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
103931868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
103941868258559ddf946fa73ef72dd43507b32623705glennrp      {
103951868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
103961868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
103971868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
103981868258559ddf946fa73ef72dd43507b32623705glennrp      }
103991868258559ddf946fa73ef72dd43507b32623705glennrp#endif
104004054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
104011868258559ddf946fa73ef72dd43507b32623705glennrp    }
104020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104031868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
104041868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
104050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104061868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
104071868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
104081868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
104090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104101868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
104111868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
104121868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
104132b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10414dec72c9b492c176af9813be3105518e91835ed37glennrp  ping_interlace_method=image_info->interlace != NoInterlace;
10415dec72c9b492c176af9813be3105518e91835ed37glennrp
10416dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_mng)
10417dec72c9b492c176af9813be3105518e91835ed37glennrp    png_set_sig_bytes(ping,8);
10418dec72c9b492c176af9813be3105518e91835ed37glennrp
10419dec72c9b492c176af9813be3105518e91835ed37glennrp  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
10420dec72c9b492c176af9813be3105518e91835ed37glennrp
10421dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_png_colortype != 0)
10422dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10423dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
10424dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10425dec72c9b492c176af9813be3105518e91835ed37glennrp         {
10426dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
10427dec72c9b492c176af9813be3105518e91835ed37glennrp
10428dec72c9b492c176af9813be3105518e91835ed37glennrp           if (ping_bit_depth < 8)
10429dec72c9b492c176af9813be3105518e91835ed37glennrp             ping_bit_depth=8;
10430dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10431dec72c9b492c176af9813be3105518e91835ed37glennrp
10432dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
10433dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10434dec72c9b492c176af9813be3105518e91835ed37glennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
10435dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10436dec72c9b492c176af9813be3105518e91835ed37glennrp
10437dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_need_colortype_warning != MagickFalse ||
10438dec72c9b492c176af9813be3105518e91835ed37glennrp     ((mng_info->write_png_depth &&
10439dec72c9b492c176af9813be3105518e91835ed37glennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
10440dec72c9b492c176af9813be3105518e91835ed37glennrp     (mng_info->write_png_colortype &&
10441dec72c9b492c176af9813be3105518e91835ed37glennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10442dec72c9b492c176af9813be3105518e91835ed37glennrp      mng_info->write_png_colortype != 7 &&
10443dec72c9b492c176af9813be3105518e91835ed37glennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
10444dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10445dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10446dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10447dec72c9b492c176af9813be3105518e91835ed37glennrp          if (ping_need_colortype_warning != MagickFalse)
10448dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10449dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10450dec72c9b492c176af9813be3105518e91835ed37glennrp                 "  Image has transparency but tRNS chunk was excluded");
10451dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10452dec72c9b492c176af9813be3105518e91835ed37glennrp
10453dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_depth)
10454dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10455dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10456dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:bit-depth=%u, Computed depth=%u",
10457dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_depth,
10458dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_bit_depth);
10459dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10460dec72c9b492c176af9813be3105518e91835ed37glennrp
10461dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_colortype)
10462dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10463dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10464dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:color-type=%u, Computed color type=%u",
10465dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_colortype-1,
10466dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_color_type);
10467dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10468dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10469dec72c9b492c176af9813be3105518e91835ed37glennrp
10470dec72c9b492c176af9813be3105518e91835ed37glennrp      png_warning(ping,
10471dec72c9b492c176af9813be3105518e91835ed37glennrp        "Cannot write image with defined png:bit-depth or png:color-type.");
10472dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10473dec72c9b492c176af9813be3105518e91835ed37glennrp
1047417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  if (image_matte != MagickFalse && image->alpha_trait == UndefinedPixelTrait)
10475dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10476dec72c9b492c176af9813be3105518e91835ed37glennrp      /* Add an opaque matte channel */
10477dec72c9b492c176af9813be3105518e91835ed37glennrp      image->alpha_trait = BlendPixelTrait;
10478dec72c9b492c176af9813be3105518e91835ed37glennrp      (void) SetImageAlpha(image,OpaqueAlpha,exception);
10479dec72c9b492c176af9813be3105518e91835ed37glennrp
10480dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10481dec72c9b492c176af9813be3105518e91835ed37glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10482dec72c9b492c176af9813be3105518e91835ed37glennrp          "  Added an opaque matte channel");
10483dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10484dec72c9b492c176af9813be3105518e91835ed37glennrp
10485dec72c9b492c176af9813be3105518e91835ed37glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10486dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10487dec72c9b492c176af9813be3105518e91835ed37glennrp      if (ping_color_type < 4)
10488dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10489dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_have_tRNS=MagickTrue;
10490dec72c9b492c176af9813be3105518e91835ed37glennrp           if (logging != MagickFalse)
10491dec72c9b492c176af9813be3105518e91835ed37glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10492dec72c9b492c176af9813be3105518e91835ed37glennrp               "  Setting ping_have_tRNS=MagickTrue.");
10493dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10494dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10495dec72c9b492c176af9813be3105518e91835ed37glennrp
10496dec72c9b492c176af9813be3105518e91835ed37glennrp  if (logging != MagickFalse)
10497dec72c9b492c176af9813be3105518e91835ed37glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10498dec72c9b492c176af9813be3105518e91835ed37glennrp      "  Writing PNG header chunks");
10499dec72c9b492c176af9813be3105518e91835ed37glennrp
10500dec72c9b492c176af9813be3105518e91835ed37glennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
10501dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_bit_depth,ping_color_type,
10502dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_interlace_method,ping_compression_method,
10503dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_filter_method);
10504dec72c9b492c176af9813be3105518e91835ed37glennrp
10505dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
10506dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10507dec72c9b492c176af9813be3105518e91835ed37glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
10508dec72c9b492c176af9813be3105518e91835ed37glennrp
10509dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10510dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10511dec72c9b492c176af9813be3105518e91835ed37glennrp          for (i=0; i< (ssize_t) number_colors; i++)
10512dec72c9b492c176af9813be3105518e91835ed37glennrp          {
10513dec72c9b492c176af9813be3105518e91835ed37glennrp            if (i < ping_num_trans)
10514dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10515dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10516dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10517dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10518dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10519dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue,
10520dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10521dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) ping_trans_alpha[i]);
10522dec72c9b492c176af9813be3105518e91835ed37glennrp             else
10523dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10524dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d)",
10525dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10526dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10527dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10528dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue);
10529dec72c9b492c176af9813be3105518e91835ed37glennrp           }
10530dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10531dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10532dec72c9b492c176af9813be3105518e91835ed37glennrp
105330d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
105340d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
105353d627862fb79aad8a20be4f1587f0b8761db441aglennrp     (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105360d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
105370d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
105380d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
105390d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
10540c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
10541c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
10542c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
105433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10544c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
105450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10546c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
10547c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
10548c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
10549c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
10550c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
1055126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
10552c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
10553c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
10554c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
10555ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10556ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          "  Setting up iCCP chunk");
105576647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
1055816ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
10559e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
10560c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
10561e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
10562120b581ad9516a43c50caedfa1a8cff418488819Cristy                         (const png_byte *) GetStringInfoDatum(profile),
10563e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
10564c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
10565918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                       ping_have_iCCP = MagickTrue;
10566c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
1056726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
105680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10569c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10571c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
10572c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
10573ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10574ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      "  Setting up zTXT chunk with uuencoded ICC");
10575cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
10576c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
10577c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
10578c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
10579ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  ping_have_iCCP = MagickTrue;
10580c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
10581c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
105820b206f5daa453dc1035db5890cabc899736dc2d0glennrp
10583c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
10584c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10585c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
105860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10587c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
10588c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
105890d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
10594ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_have_iCCP != MagickTrue &&
10595ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      (ping_have_sRGB != MagickFalse ||
10596ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1059826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
1059926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1060026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
1060126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
1060226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
1060326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
1060426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1060526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
106060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1060726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
10608cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
10609cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
10610918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp
10611918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB = MagickTrue;
1061226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1061426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
106155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106182cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
10619918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_iCCP == MagickFalse &&
10620918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB == MagickFalse &&
106212cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
1062226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
1062326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
106333b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1063626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
106372b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10638918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp      if (ping_exclude_cHRM == MagickFalse && ping_have_sRGB == MagickFalse)
106393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1064026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
1064126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
1064226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
1064326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
1064426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
10645918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                Note: if cHRM+gAMA == sRGB write sRGB instead.
1064626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
1064726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
1064826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
1064926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
1065026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
1065126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
1065226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1065326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1065426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1065526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1065626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1065726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1065826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1065926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1066026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1066126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1066226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1066326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1066426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1066526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10667dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1066826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1066926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1067026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10671c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1067226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
106738fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10674c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10675c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10676c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10677c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10678c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10679c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10680c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10681c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10682c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10683c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10684c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10685c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10686c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10687c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1068826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10689991d11dd9c33e65872778b81aff1347cd2878154glennrp
1069026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10691dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1069226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1069326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1069426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1069526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1069626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1069726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10698823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
106998fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10700823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10701823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10702823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10703823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10704823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10705823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10706823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10707823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10708823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10709823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10710823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10711823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10712823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1071326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10714dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10715dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10716dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
107174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10718dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1071926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1072026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1072126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1072226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10723dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1072426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1072526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1072626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1072726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1072826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10729dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10730dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10731dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10732fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
10733fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (ping_exclude_tIME == MagickFalse)
10734fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
10735fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      const char
10736fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        *timestamp;
10737fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
1073839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      if (image->taint == MagickFalse)
10739fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
1074039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          timestamp=GetImageOption(image_info,"png:tIME");
1074139d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1074239d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          if (timestamp == (const char *) NULL)
10743fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            timestamp=GetImageProperty(image,"png:tIME",exception);
10744fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
1074539d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1074639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      else
1074739d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp        {
1074839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1074939d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp             "  Reset tIME in tainted image");
1075039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1075139d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          timestamp=GetImageProperty(image,"date:modify",exception);
1075239d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp        }
1075339d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1075439d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      if (timestamp != (const char *) NULL)
1075539d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          write_tIME_chunk(image,ping,ping_info,timestamp,exception);
10756fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
10757fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
107586647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
10759da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10760da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1076116ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10762da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10763da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10764da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10765da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10766da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10767da8f3a7bfddac2680a3069a490db541e7944edafglennrp
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10769991d11dd9c33e65872778b81aff1347cd2878154glennrp
1077039992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10771991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
107723b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
107730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
107760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10777991d11dd9c33e65872778b81aff1347cd2878154glennrp
107780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
107790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
107800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
107810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
107820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10783991d11dd9c33e65872778b81aff1347cd2878154glennrp
107840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
107850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
107870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
107880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
107890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
107900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107913b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
107920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
107930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10794c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
107950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
107960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
107970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
107980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
107990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
108000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10801991d11dd9c33e65872778b81aff1347cd2878154glennrp
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10803cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10804da8f3a7bfddac2680a3069a490db541e7944edafglennrp
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10806991d11dd9c33e65872778b81aff1347cd2878154glennrp
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10808cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1081026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
108134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1081426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1081526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1081626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1081726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1081826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1081926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1082003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1082126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1082226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1082326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1082426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1082526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1082626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
108309c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
108329c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10841b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10842b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
108437202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10845b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10847b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
108480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10849b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10850b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10851b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
108520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10853b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10855b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
108560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10857b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10858b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108603b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
108613b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
108623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10863b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10864b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
108650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10866b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10867e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108690997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=AcquireVirtualMemory(rowbytes,sizeof(*ping_pixels));
108700997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
10871edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Allocation of memory for pixels failed");
108720997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
108730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108775f766ef8b0cd9906c2c3a56d845828380a251073cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10878ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10879edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation for quantum_info failed");
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
10881e63d2029af2dd8bedf895fdb63d79d0f0f9c2671dirk  SetQuantumDepth(image,quantum_info,image_depth);
108824b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
108848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10886fd164d2bf84b111e304959af5698757d60e9b8aeglennrp       !mng_info->write_png48 && !mng_info->write_png64 &&
108878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
108888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
108908d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
108918d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1089416ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
108960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108976e3531932372c9bea14d4a6d1c6eb9026658f9b4Cristy      SetQuantumDepth(image,quantum_info,8);
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10903bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10905d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
109063b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109073b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10908a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1090916ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
109100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1091116ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
109130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1091616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1091716ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
109183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10923bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10924cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
109253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
109263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
109273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
109280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1093116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1093216ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
109333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
109340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10936bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10937cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
109390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109403b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10941b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10942b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
109430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10944cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
10945af9320404a7b05014476f844b11110157a21b73eglennrp
10946d5a9b370d73940f19035e55634c15c77714031b8dirk          status=SetImageProgress(image,SaveImageTag,
10947af9320404a7b05014476f844b11110157a21b73eglennrp              (MagickOffsetType) (pass * image->rows + y),
10948af9320404a7b05014476f844b11110157a21b73eglennrp              num_passes * image->rows);
1094944c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
10950af9320404a7b05014476f844b11110157a21b73eglennrp          if (status == MagickFalse)
10951af9320404a7b05014476f844b11110157a21b73eglennrp            break;
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10959fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png48 && !mng_info->write_png64 &&
10960fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png32) && (image_matte != MagickFalse ||
10961fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
10962fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (mng_info->IsPalette) && ping_have_color == MagickFalse)
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1096416ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
109658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
109660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10970bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
109713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1097216ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
109732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1097416ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
109753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
109762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1098016ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1098116ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
109822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1098416ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1098516ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
109862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
109888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
109903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10993b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
109943b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10995b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
109972cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1099816ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1099916ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
11000b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
110012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110023b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
11003b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
110052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11006cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
110072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11008d5a9b370d73940f19035e55634c15c77714031b8dirk            status=SetImageProgress(image,SaveImageTag,
11009af9320404a7b05014476f844b11110157a21b73eglennrp              (MagickOffsetType) (pass * image->rows + y),
11010af9320404a7b05014476f844b11110157a21b73eglennrp              num_passes * image->rows);
1101144c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
11012af9320404a7b05014476f844b11110157a21b73eglennrp            if (status == MagickFalse)
11013af9320404a7b05014476f844b11110157a21b73eglennrp              break;
110148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
110158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
110168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
110170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1102016ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
110218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
110220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
11025fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            if ((image_depth > 8) ||
11026fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 ||
110278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
11028fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 ||
11029fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png64 ||
11030fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
110318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
110328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
11033b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
11034862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
110352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1103616ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
110378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
110408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
110418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1104216ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1104316ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
110442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1104616ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1104716ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
110488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
110492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
110518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1105216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
11053cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1105416ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
110552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
110578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
110598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
110602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1106216ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1106316ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
110642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1106616ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1106716ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
110682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110693b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
11070b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
110722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11073cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
11074af9320404a7b05014476f844b11110157a21b73eglennrp
11075d5a9b370d73940f19035e55634c15c77714031b8dirk                status=SetImageProgress(image,SaveImageTag,
11076af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) (pass * image->rows + y),
11077af9320404a7b05014476f844b11110157a21b73eglennrp                  num_passes * image->rows);
1107844c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
11079af9320404a7b05014476f844b11110157a21b73eglennrp                if (status == MagickFalse)
11080af9320404a7b05014476f844b11110157a21b73eglennrp                  break;
11081b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
110828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
110832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
11085fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            /* not ((image_depth > 8) ||
11086fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 || mng_info->write_png32 ||
11087fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 || mng_info->write_png64 ||
11088fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
11089fd164d2bf84b111e304959af5698757d60e9b8aeglennrp             */
110908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
110918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
110928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
110938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
110948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
110958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
110972cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110986e3531932372c9bea14d4a6d1c6eb9026658f9b4Cristy                  SetQuantumDepth(image,quantum_info,8);
110998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
111008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
111012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
111028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
111038640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
111048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
111058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
111072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1110816ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
111092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1111016ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
111118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
111122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
111138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1111444757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
111156e3531932372c9bea14d4a6d1c6eb9026658f9b4Cristy                    SetQuantumDepth(image,quantum_info,image->depth);
111164bf89731a90c6e03598950223e19e7be7b95d630glennrp
1111716ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1111816ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1111944757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
111202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
111218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
111228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
111238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
111248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
111262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1112716ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
11128cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1112916ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
111308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
111312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
111328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
111338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1113416ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1113516ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
111362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
111375eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
111385eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
111395eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111401a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
111415eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
111425eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111435eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
111445eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
111455eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
111468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
11147cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
111482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11149d5a9b370d73940f19035e55634c15c77714031b8dirk                status=SetImageProgress(image,SaveImageTag,
11150af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) (pass * image->rows + y),
11151af9320404a7b05014476f844b11110157a21b73eglennrp                  num_passes * image->rows);
1115244c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
111538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
111548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
111558640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
11156af9320404a7b05014476f844b11110157a21b73eglennrp            }
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
111608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
11161b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
11162b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11167b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
111680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11170e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
111710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11173e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
111740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
111763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111785d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
111793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
111830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
111853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111875d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
111883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
111920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11197a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
111983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11199823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1120126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1120226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1120326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1120426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1120526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1120626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
112072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1120816ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
11209a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11210e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      /* Don't write any "png:" or "jpeg:" properties; those are just for
11211e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       * "identify" or for passing through to another JPEG
11212e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       */
11213e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      if ((LocaleNCompare(property,"png:",4) != 0 &&
11214a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp           LocaleNCompare(property,"jpeg:",5) != 0) &&
11215e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp
11216a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11217a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
11218a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
11219823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
11220a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
11221a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11222a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
11223a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
11224a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1122526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
11226c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
11227c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
11228a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy
11229ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
11230a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,
11231a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy                 (png_alloc_size_t) sizeof(png_text));
11232a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
11233a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
11234a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
11235c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
11236c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
11237c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
112382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11239c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
11240c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
112412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11242c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
11243c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
112442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11245c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1124626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
11247c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
11248c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
11249c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
11250c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1125126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
112522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11253c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
11254c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
11255c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11256c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
11257c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11258c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11259cbc9215c23fce410bf0bea825dee908c15271bb3glennrp                  "    keyword: '%s'",text[0].key);
11260c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
11261c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11262c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
11263c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
11264c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1126526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1126626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1126726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
112683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
112693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
11271cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
112723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
112760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
112780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
112803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
112825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
112835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
112843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
112873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
112893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1129303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
113013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
113023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
113033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
113045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
113075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
113093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
113113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
113130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
113163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
113183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
11319edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
113200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
113223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
113233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
113245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
113253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113270997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
113283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1132916ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1133016ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1133116ea139d53d867211d3bb0fa859a83de653f687ecristy
1133216ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1133316ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1133416ea139d53d867211d3bb0fa859a83de653f687ecristy
11335b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
11336b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
11337b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
11338b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1133916ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
11340b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
113413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
113423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
113440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11345868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
11346edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
11347edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
11348edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
11349edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   /* }  for navigation to beginning of SETJMP-protected block. Revert to
11350edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    *    Throwing an Exception when an error occurs.
11351edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    */
11352edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
113533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
113543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
11355edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
113563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
113573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
113593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
113643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
113703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
113713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
113733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
113753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1137616ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1137716ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
113783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
113803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
113843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1138516ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1138616ea139d53d867211d3bb0fa859a83de653f687ecristy%
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
113903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
113935d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113955a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
113965a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
113995a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
114005a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
11401e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
11402130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
11403130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
11404130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
11405e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
11406e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
11407e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
114085a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
114095a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
114103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
114115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
114125a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
114135a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
114163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
114175a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
114185a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
114195a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
114205a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
114215a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
114243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
114260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
114275a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
114285a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
114293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11430fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG48:   A 16-bit per sample RGB PNG datastream is written.  The tRNS
11431fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               chunk can be present to convey binary transparency by naming
11432fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               one of the colors as transparent.  If the image has more
11433fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               than one transparent color, has semitransparent pixels, or
11434fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               has an opaque pixel with the same RGB components as the
11435fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparent color, an image is not written.
11436fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
11437fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG64:   A 16-bit per sample RGBA PNG is written.  Partial
11438fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparency is permitted, i.e., the alpha sample for
11439fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               each pixel can have any value from 0 to 65535. The alpha
11440fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               channel is present even if the image is fully opaque.
11441fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
114425830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%    o PNG00:   A PNG that inherits its colortype and bit-depth from the input
114435830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               image, if the input was a PNG, is written.  If these values
11444c1e07709d63f88437cf56ddbc6b3889a96711346glennrp%               cannot be found, or if the pixels have been changed in a way
11445c1e07709d63f88437cf56ddbc6b3889a96711346glennrp%               that makes this impossible, then "PNG00" falls back to the
11446c1e07709d63f88437cf56ddbc6b3889a96711346glennrp%               regular "PNG" format.
114475830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%
114483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
114493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
114503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
11451bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
11452bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
11453bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
114543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
114563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
114593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
114613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
114643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
114663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
114693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
114703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11471fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               If the image cannot be written without loss with the
11472fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               requested bit-depth and color-type, a PNG file will not
11473fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               be written, a warning will be issued, and the encoder will
11474fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               return MagickFalse.
114755a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
114795a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1148016ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
114813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
114873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
114883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
11495bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
11496bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
114973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
11501bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11503bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
115043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
115053241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
115060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
11507d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
115080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
115090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
115100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
11511cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
115120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
11513d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
11514d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
115155d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
11516d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
11517d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
11518d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
11519d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
115200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
115213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
115233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1152416ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
115253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
115263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1152721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1152821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1152921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
115303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
115313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
115333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
115343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
115363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
115373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
115395c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
115405c7cf4e469a4dad7e277783749155932252c52dfglennrp
115413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
115423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
115433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
115443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
11545e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
115463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
11547e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
115483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11549fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
115503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
115513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
115523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
115533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1155473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
115550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
115573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
115580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
115603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
115613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
115623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
115633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
11564a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
115653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
115663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
115683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
115703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
115713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
11572fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png48=LocaleCompare(image_info->magick,"PNG48") == 0;
11573fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png64=LocaleCompare(image_info->magick,"PNG64") == 0;
115743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11575092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:format");
11576b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
115775a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp  if (value != (char *) NULL || LocaleCompare(image_info->magick,"PNG00") == 0)
11578b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
11579f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11580f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp         "  Format=%s",value);
11581f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11582fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png8 = MagickFalse;
11583fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png24 = MagickFalse;
11584fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png32 = MagickFalse;
11585fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png48 = MagickFalse;
11586fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png64 = MagickFalse;
11587fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11588b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
11589b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
11590b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11591b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11592b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11593b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11594b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11595b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11596fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11597fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png48") == 0)
11598fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png48 = MagickTrue;
11599fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11600fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png64") == 0)
11601fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png64 = MagickTrue;
116025830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
116035a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp      else if ((LocaleCompare(value,"png00") == 0) ||
116045a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp         LocaleCompare(image_info->magick,"PNG00") == 0)
116055830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        {
116063398b5b62521b49754d9391aae9e4511857bd63bglennrp          /* Retrieve png:IHDR.bit-depth-orig and png:IHDR.color-type-orig. */
116073398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.bit-depth-orig",exception);
116086647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11609f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11610f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11611f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11612f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited bit depth=%s",value);
116136647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11614f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"1") == 0)
11615f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 1;
116166647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
116175a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"2") == 0)
11618f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 2;
116196647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
116205a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"4") == 0)
11621f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 4;
116226647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11623f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"8") == 0)
11624f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 8;
116256647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11626f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"16") == 0)
11627f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 16;
11628f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
116296647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
116303398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.color-type-orig",exception);
116316647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11632f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11633f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11634f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11635f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited color type=%s",value);
116366647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11637f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"0") == 0)
11638f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 1;
116396647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11640f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"2") == 0)
11641f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 3;
116426647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11643f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"3") == 0)
11644f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 4;
116456647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11646f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"4") == 0)
11647f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 5;
116486647b972c570ebc4fa9d4e6ac9a7e4a615adf855glennrp
11649f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"6") == 0)
11650f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 7;
11651f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
116525830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        }
116535830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
116545830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
116553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116579c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
116589c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
116599c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
116603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
116633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116649c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
116659c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
116669c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
116670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1166817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      if (image->alpha_trait != UndefinedPixelTrait)
11669def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,TrueColorAlphaType,exception);
116700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116719c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1167216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
116730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1167416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
116783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116799c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
116809c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
116819c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
1168247da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
116830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11684def23e5d7331b1a13ed593b6d6aca516da382328cristy      (void) SetImageType(image,TrueColorAlphaType,exception);
1168516ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11688fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48)
11689fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11690fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 2 */ 3;
11691fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11692fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
11693fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
1169417f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      if (image->alpha_trait != UndefinedPixelTrait)
11695def23e5d7331b1a13ed593b6d6aca516da382328cristy        (void) SetImageType(image,TrueColorAlphaType,exception);
11696fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11697fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else
116984dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorType,exception);
11699fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
117004dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11701fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11702fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11703fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png64)
11704fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11705fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 6 */  7;
11706fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11707fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
1170847da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
11709fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11710def23e5d7331b1a13ed593b6d6aca516da382328cristy      (void) SetImageType(image,TrueColorAlphaType,exception);
117114dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11712fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11713fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11714092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:bit-depth");
117158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
117163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
117173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
117183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
117199c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
117200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
117229c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
117230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
117259c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
117260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
117289c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
117290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
117319c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
117320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11733bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1173416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11735bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11736bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11737bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11738bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
117393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
117409c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11741bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
117423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
117430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11744092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:color-type");
117450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
117473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
117483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
117493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
117509c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
117510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1175216ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1175316ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1175416ea139d53d867211d3bb0fa859a83de653f687ecristy
117553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
117569c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
117570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
117599c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
117600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
117629c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
117630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
117659c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
117660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11767bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1176816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11769bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11770bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11771bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11772bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
117733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
117749c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11775d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
117763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
117773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
117790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117800dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
117810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
117820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117835d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
117840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
117850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
117860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
117870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
117880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
117900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117915d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
117925d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
117930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
117940dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
117950dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
117960dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11797aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11798aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11799aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
118000e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
118010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
118020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
118030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
118040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
118050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
118060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
118070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
118080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
118090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
118100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
118110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
118120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11813104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
118140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
118150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1181626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1181726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11818a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1181926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1182026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1182126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1182226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1182326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1182426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1182526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1182626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11827fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  mng_info->ping_exclude_tIME=MagickFalse;
11828a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1182926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1183026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1183126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1183226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
118338d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
118348d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11835092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:preserve-colormap");
118368d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
118378b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:preserve-colormap");
118388d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
118398d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
118408d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11841ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  mng_info->ping_preserve_iCCP=MagickFalse;
11842ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11843ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  value=GetImageOption(image_info,"png:preserve-iCCP");
11844ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value == NULL)
11845ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     value=GetImageArtifact(image,"png:preserve-iCCP");
11846ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value != NULL)
11847ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     mng_info->ping_preserve_iCCP=MagickTrue;
11848ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11849ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  /* These compression-level, compression-strategy, and compression-filter
118501868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
118511868258559ddf946fa73ef72dd43507b32623705glennrp   */
11852092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-level");
118531868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118548b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-level");
118551868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118561868258559ddf946fa73ef72dd43507b32623705glennrp  {
118571868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
118581868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
118591868258559ddf946fa73ef72dd43507b32623705glennrp       */
118601868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118611868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
118621868258559ddf946fa73ef72dd43507b32623705glennrp
118630ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
118641868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
118651868258559ddf946fa73ef72dd43507b32623705glennrp
118661868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118671868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
118681868258559ddf946fa73ef72dd43507b32623705glennrp
118691868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118701868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
118711868258559ddf946fa73ef72dd43507b32623705glennrp
118721868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118731868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
118741868258559ddf946fa73ef72dd43507b32623705glennrp
118751868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118761868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
118771868258559ddf946fa73ef72dd43507b32623705glennrp
118781868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
118791868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
118801868258559ddf946fa73ef72dd43507b32623705glennrp
118811868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
118821868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
118831868258559ddf946fa73ef72dd43507b32623705glennrp
118841868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
118851868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
118861868258559ddf946fa73ef72dd43507b32623705glennrp
118871868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
118881868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
118891868258559ddf946fa73ef72dd43507b32623705glennrp
118901868258559ddf946fa73ef72dd43507b32623705glennrp      else
1189116ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118921868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118931868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
118941868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118951868258559ddf946fa73ef72dd43507b32623705glennrp    }
118961868258559ddf946fa73ef72dd43507b32623705glennrp
11897092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-strategy");
118981868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118998b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-strategy");
119001868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
119011868258559ddf946fa73ef72dd43507b32623705glennrp  {
119021868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
119031868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
119041868258559ddf946fa73ef72dd43507b32623705glennrp
119051868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
119061868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
119071868258559ddf946fa73ef72dd43507b32623705glennrp
119081868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
119091868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
119101868258559ddf946fa73ef72dd43507b32623705glennrp
119111868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1191298c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
119131868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1191498c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1191598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1191698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
119171868258559ddf946fa73ef72dd43507b32623705glennrp
119181868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1191998c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
119201868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1192198c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1192298c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1192398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
119241868258559ddf946fa73ef72dd43507b32623705glennrp
119251868258559ddf946fa73ef72dd43507b32623705glennrp      else
1192616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
119271868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
119281868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
119291868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
119301868258559ddf946fa73ef72dd43507b32623705glennrp    }
119311868258559ddf946fa73ef72dd43507b32623705glennrp
11932092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-filter");
119331868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
119348b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-filter");
119351868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
119361868258559ddf946fa73ef72dd43507b32623705glennrp  {
119371868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
119381868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
119391868258559ddf946fa73ef72dd43507b32623705glennrp       *
119401868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
119411868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
119421868258559ddf946fa73ef72dd43507b32623705glennrp       */
119431868258559ddf946fa73ef72dd43507b32623705glennrp
119441868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
119451868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
119461868258559ddf946fa73ef72dd43507b32623705glennrp
11947b19b8125320afb5954bd73b82d00700e8ed9e984cristy      else if (LocaleCompare(value,"1") == 0)
119481868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
119491868258559ddf946fa73ef72dd43507b32623705glennrp
119501868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
119511868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
119521868258559ddf946fa73ef72dd43507b32623705glennrp
119531868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
119541868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
119551868258559ddf946fa73ef72dd43507b32623705glennrp
119561868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
119571868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
119581868258559ddf946fa73ef72dd43507b32623705glennrp
119591868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
119601868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
119611868258559ddf946fa73ef72dd43507b32623705glennrp
119621868258559ddf946fa73ef72dd43507b32623705glennrp      else
1196316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
119641868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
119651868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
119661868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
119671a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  }
1196803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
119691a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  for (source=0; source<8; source++)
119705c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
119711a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    value = NULL;
11972acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
119732dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 0)
119742dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunks");
119752dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119762dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 1)
119772dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunks");
119782dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119792dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 2)
119802dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunk");
119812dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119822dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 3)
119832dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunk");
119842dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119852dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 4)
119862dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunks");
119872dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119882dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 5)
119892dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunks");
119902dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119912dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 6)
119922dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunk");
119932dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119942dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 7)
119952dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunk");
1199626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
119971a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (value == NULL)
119981a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp       continue;
119991a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp
120001a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (source < 4)
120011a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickTrue;
120021a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    else
120031a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickFalse;
1200426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1200503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
120062cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
120071a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        if (source == 0 || source == 2)
120081a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120091a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:exclude-chunk=%s found in image options.\n", value);
120101a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 1 || source == 3)
120112cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120122cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
120131a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 4 || source == 6)
120142cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120151a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image options.\n", value);
120161a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else /* if (source == 5 || source == 7) */
120171a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120181a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
120192cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1202003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
120211a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (IsOptionMember("all",value) != MagickFalse)
120221a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
120231a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_bKGD=excluding;
120241a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_cHRM=excluding;
120251a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_date=excluding;
120261a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_EXIF=excluding;
120271a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_gAMA=excluding;
120281a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_iCCP=excluding;
120291a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=excluding; */
120301a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_oFFs=excluding;
120311a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_pHYs=excluding;
120321a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_sRGB=excluding;
120331a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tEXt=excluding;
12034fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding;
120351a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tRNS=excluding;
120361a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_vpAg=excluding;
120371a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zCCP=excluding;
120381a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zTXt=excluding;
120391a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
12040280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp
12041689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("none",value) != MagickFalse)
120421a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
12043a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_bKGD=excluding != MagickFalse ? MagickFalse :
12044a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12045a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_cHRM=excluding != MagickFalse ? MagickFalse :
12046a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12047a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_date=excluding != MagickFalse ? MagickFalse :
12048a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12049a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_EXIF=excluding != MagickFalse ? MagickFalse :
12050a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12051a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_gAMA=excluding != MagickFalse ? MagickFalse :
12052a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12053a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_iCCP=excluding != MagickFalse ? MagickFalse :
12054a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
120551a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=!excluding; */
12056a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_oFFs=excluding != MagickFalse ? MagickFalse :
12057a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12058a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_pHYs=excluding != MagickFalse ? MagickFalse :
12059a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12060a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_sRGB=excluding != MagickFalse ? MagickFalse :
12061a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12062a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tEXt=excluding != MagickFalse ? MagickFalse :
12063a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12064fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding != MagickFalse ? MagickFalse :
12065fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          MagickTrue;
12066a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tRNS=excluding != MagickFalse ? MagickFalse :
12067a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12068a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_vpAg=excluding != MagickFalse ? MagickFalse :
12069a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12070a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zCCP=excluding != MagickFalse ? MagickFalse :
12071a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12072a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zTXt=excluding != MagickFalse ? MagickFalse :
12073a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
120741a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
1207503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
12076689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("bkgd",value) != MagickFalse)
120771a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_bKGD=excluding;
120782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12079689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("chrm",value) != MagickFalse)
120801a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_cHRM=excluding;
12081a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
12082689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("date",value) != MagickFalse)
120831a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_date=excluding;
120842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12085689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("exif",value) != MagickFalse)
120861a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_EXIF=excluding;
120872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12088689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("gama",value) != MagickFalse)
120891a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_gAMA=excluding;
120902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12091689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("iccp",value) != MagickFalse)
120921a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iCCP=excluding;
120932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12094689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
12095689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("itxt",value) != MagickFalse)
120961a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iTXt=excluding;
12097689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
120982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12099689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("offs",value) != MagickFalse)
121001a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_oFFs=excluding;
121012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12102689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("phys",value) != MagickFalse)
121031a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_pHYs=excluding;
121042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12105689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("srgb",value) != MagickFalse)
121061a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_sRGB=excluding;
121072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12108689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("text",value) != MagickFalse)
121091a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tEXt=excluding;
121102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12111fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (IsOptionMember("time",value) != MagickFalse)
12112fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      mng_info->ping_exclude_tIME=excluding;
12113fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
12114689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("trns",value) != MagickFalse)
121151a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tRNS=excluding;
12116a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
12117689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("vpag",value) != MagickFalse)
121181a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_vpAg=excluding;
121192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12120689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("zccp",value) != MagickFalse)
121211a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zCCP=excluding;
121222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12123689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("ztxt",value) != MagickFalse)
121241a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zTXt=excluding;
1212526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1212626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
121271a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  if (logging != MagickFalse)
1212826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1212926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
121305d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1213126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1213226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1213326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1213426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1213526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1213626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
12137a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
12138a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12139a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1214026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1214126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1214226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1214326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1214426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1214526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1214626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1214726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1214826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
12149689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
1215026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1215126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1215226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
12153689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
12154689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp
1215526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1215626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1215726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1215826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1215926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1216026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1216126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1216226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1216326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1216426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1216526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1216626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
12167fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (mng_info->ping_exclude_tIME != MagickFalse)
12168fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12169fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          "    tIME");
12170a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
12171a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12172a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1217326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1217426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1217526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1217626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1217726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1217826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1217926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1218026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1218126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1218226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1218326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
12184b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
121853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1218616ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
121873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
121890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
121920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
121943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
121953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
121973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
121993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1220016ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
122013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
122023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
122033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
122043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
122063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
122073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1220903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
122103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
122113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
122133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
122143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
122163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
122173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
122183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
122193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
122213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
122223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
122233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
122243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
122253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12226bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1222759575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
122283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
122293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
12231fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
122323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
122343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
122353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
122367e99a06aa771c9e270e7940731dbf9f2ab2c09b1glennrp  length=0;
122373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
12239def23e5d7331b1a13ed593b6d6aca516da382328cristy  transparent=image_info->type==GrayscaleAlphaType ||
1224044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp     image_info->type==TrueColorAlphaType ||
1224144c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp     image->alpha_trait != UndefinedPixelTrait;
122423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122434b917593e694424be469d250448c05c878663812glennrp  jng_alpha_sample_depth = 0;
122444b917593e694424be469d250448c05c878663812glennrp
1224559575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1224659575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1224759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1224859575fa5c228308a41d7f5028390be2083aaaf6dglennrp
12249750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1225059575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1225159575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1225259575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1225359575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
122543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12255d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  length=0;
12256d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
122578fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
122583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
122600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
122623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1226416ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
122650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
122670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
122693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
122723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
122740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1227516ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
122763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
12278151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MagickPathExtent);
122798a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      jpeg_image->alpha_trait=UndefinedPixelTrait;
122808f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1228116ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1228216ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
12284151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(jpeg_image_info->filename,MagickPathExtent,
122853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
122863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1228759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1228859575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1228959575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1229059575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1229159575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1229259575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
122933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
12297def23e5d7331b1a13ed593b6d6aca516da382328cristy  if (image_info->type != TrueColorAlphaType && image_info->type !=
12298f1d8548abecaf5ca89d453fd9fc0cde77d20672bdirk    TrueColorType && SetImageGray(image,exception))
122993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
123003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1230159575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1230259575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1230359575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1230459575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1230559575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1230659575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
123078fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (transparent != 0)
1230859575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1230959575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1231059575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1231159575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1231259575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1231359575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1231459575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1231559575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1231659575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1231759575fa5c228308a41d7f5028390be2083aaaf6dglennrp
123188fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
123193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
123203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1232516ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1232716ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
1232844c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp          if (status == MagickFalse)
1232944c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1233044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
123313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
123323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
123343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12335151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MagickPathExtent);
12336151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MagickPathExtent);
123373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12339cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
12340cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
12341cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
12342b3f97ae45019a91b30792a6fa42d81a2689a7025cristy          blob=(unsigned char *) ImageToBlob(jpeg_image_info,jpeg_image,
12343b3f97ae45019a91b30792a6fa42d81a2689a7025cristy            &length,exception);
123443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1234616ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
123473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
123483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
123493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
123503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
123513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1235216ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
123533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1235516ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
1235644c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp          if (status == MagickFalse)
1235744c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1235844c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
123593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12360151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MagickPathExtent);
12361151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MagickPathExtent);
123623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
123633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
12366b3f97ae45019a91b30792a6fa42d81a2689a7025cristy          blob=(unsigned char *) ImageToBlob(jpeg_image_info,jpeg_image,&length,
1236716ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
123683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
123690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12372e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
12373e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
123743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
123763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
123803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
123833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1238503812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
123864e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
123874e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
123883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
123893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
123923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
123933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
123963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
123973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
123983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12401f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
124020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12404f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
124050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
124080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
124110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
124140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
124170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
124200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
124230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
124260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
124293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
12432cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
124333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
124353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
124363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
124373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124388fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
124403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
124453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
124463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
124473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
124483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12449bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
124503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
124513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
124533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
124543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
124553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
12456bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
124573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1245803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
124593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
124603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
124613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
124623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
124633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
124643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
124653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
124683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
124693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
124703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
124713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
124733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
124763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
124783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1247903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
124800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
12482e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12483cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12484e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
124850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12487e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12488cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12489e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
124900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
124923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
124933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
124953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
124973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
125003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
125013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1250303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1250435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
125053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
125103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
125113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
125133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
125163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
125173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1252003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
125213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1252235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1252335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
125243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1252535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1252635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1252835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1252935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
125303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1253135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1253235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1253816ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
125393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
125433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
125443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1254503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
125463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
125473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1254835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1254916ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
125500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1255135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1255216ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
125530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
125583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
125603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1256135ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1256216ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
125630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1256435ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1256516ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
125660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
125683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
125713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1257216ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1257316ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
125753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
125843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
125873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1258803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12589bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12590bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
125963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1259903812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
126003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
126043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
126053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126078fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
126083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
126093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
126103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
126123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
126133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12614fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy          size_t
126153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
126183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
126193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12620e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12621f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
126223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
126243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
126253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12626bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
126273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12628931319b135549a7266ccb46482af6e3ea9468747Cristy            len=(size_t) (*p) << 24;
12629931319b135549a7266ccb46482af6e3ea9468747Cristy            len|=(size_t) (*(p+1)) << 16;
12630931319b135549a7266ccb46482af6e3ea9468747Cristy            len|=(size_t) (*(p+2)) << 8;
12631931319b135549a7266ccb46482af6e3ea9468747Cristy            len|=(size_t) (*(p+3));
126323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
126330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
126353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
126363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12637fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image,len);
12638fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                LogPNGChunk(logging,mng_IDAT,len);
12639fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlob(image,len+4,p);
12640fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image, crc32(0,p,(uInt) len+4));
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
126420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
126443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
126453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
126463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12647e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12648e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
126493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
126503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
126513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
126523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
126537e99a06aa771c9e270e7940731dbf9f2ab2c09b1glennrp      else if (length != 0)
126543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
126553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
126573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12658e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12659bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1266103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
126643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
126683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
126723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
126753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
126773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
126783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1268316ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
12686151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MagickPathExtent);
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
12689151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) FormatLocaleString(jpeg_image_info->filename,MagickPathExtent,"%s",
126903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1269316ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12697e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12698e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
126993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1270044c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp  if (status == MagickFalse)
1270144c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1270244c22978c1f9d4cc6499a3f69de56d83f36080fdglennrp
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
127050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1270659575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1270759575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
12708151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MagickPathExtent);
12709151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MagickPathExtent);
127100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
127133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
127140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12715b3f97ae45019a91b30792a6fa42d81a2689a7025cristy  blob=(unsigned char *) ImageToBlob(jpeg_image_info,jpeg_image,&length,
12716b3f97ae45019a91b30792a6fa42d81a2689a7025cristy    exception);
127170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
127193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
127203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12721e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12722e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12725e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
127270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12729bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
127303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1273103812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
127323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
127333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
127343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
127373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
127383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
127393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12742cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
127433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
127453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
127463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1274703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
127523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
127533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
127540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
127563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
127573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
127603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
127753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1277616ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1277716ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
127783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
127803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
127823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1278516ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1278616ea139d53d867211d3bb0fa859a83de653f687ecristy%
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1278916ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1279016ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1279321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1279403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
12804e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
12806e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
128073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12808fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1280916ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
128113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
128128320f8b3b9670410e3e1b6f23f6de429d8f2102eCristy  if ((image->columns > 65535UL) || (image->rows > 65535UL))
128138320f8b3b9670410e3e1b6f23f6de429d8f2102eCristy    ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
128143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1281973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
128213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
128263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1283116ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
128323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
128333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
128373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
128383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1284216ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1284316ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
128453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
128473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1285221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1285503812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1285603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1285703812ae402fb53d548f0e1d7d14720768f803c2dglennrp
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
128603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
128633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
128673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
128683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
128743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12875bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
128763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
128793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
128803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
128823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
128833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
128843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12885bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
128863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
128873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12888bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
128893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
128903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
128913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12892d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
128933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
128963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
129003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
129013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
12902e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
129033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
12904e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
129053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12906fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1290716ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
129083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
129093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
129123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
129133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1291573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
129163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
129183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
129203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
129243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
129273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
129283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
129293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
129303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
129313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
129323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
129343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
129363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
129393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
129403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
129423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
129433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
129443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
129503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
129523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129552dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "  Checking input image(s)\n"
129562dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    Image_info depth: %.20g,    Type: %d",
129572dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) image_info->depth, image_info->type);
129583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
129603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
129613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12964280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           "    Scene: %.20g\n,   Image depth: %.20g",
12965280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           (double) scene++, (double) p->depth);
129660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1296717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (p->alpha_trait != UndefinedPixelTrait)
129683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
129700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
129740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
129763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
129780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
129820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
129843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12985e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
129860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
129900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
129923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
129973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
129983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
129993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
130043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
130073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
130083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
130093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
130103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
130113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
130123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
130133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
130153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
130163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
130173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
130183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
130193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
130203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
130243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
130253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
130263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
130283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
130293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
130303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
130313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
130323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
130333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
130353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
130363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
130373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
130383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
130393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
130403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
130413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
130443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
130453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
130463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
130483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
130493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
130503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
130530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
130563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
130600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1306117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (next_image->alpha_trait != UndefinedPixelTrait)
130623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
130630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
1306517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy          if ((next_image->alpha_trait != UndefinedPixelTrait) ||
13066dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy               next_image->page.x || next_image->page.y ||
130673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
130700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
130723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
130730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
130750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
130773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
130783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
130790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
130833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
130843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
1308517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy        if (image->alpha_trait != UndefinedPixelTrait)
130863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
130870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
130893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
13090f1d8548abecaf5ca89d453fd9fc0cde77d20672bdirk            if (SetImageGray(image,exception) == MagickFalse)
130913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
130923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
130933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
130943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
130953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
130963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
130993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
131003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
131013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
131023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
131033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
131043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
131070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
131100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
131123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
131133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
131140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1311616ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1311716ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
131183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
131190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
131213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
131223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
131233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
131243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
131273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
131293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
131303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
131313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
131333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
131343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
131353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
131363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
131373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
131383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
131393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
131403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
131413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
131423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
131433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
131463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
131473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
131493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
131503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
131513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
131533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
131543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
131553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
131563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
131570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
131593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
131613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
131623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
131633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
131643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
131653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
131673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
131683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
131693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
131703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
131710261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
13172d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
13173d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1317416ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1317516ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
13176d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
13177d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
13178d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
131793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
131803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
131823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
13184cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
13185cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
131863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
131873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
131880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
131903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
131910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
131933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
131940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
131963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
13197b9d46a1991a7ff58b567caff7ab7461dfe8cb7c7cristy            (final_delay != 25) && (final_delay != 50) &&
131980bf214346985a874b4fdc1e2631983bfea5155cddirk            (final_delay != (size_t) image->ticks_per_second))
131993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
132003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
13203b9d46a1991a7ff58b567caff7ab7461dfe8cb7c7cristy        mng_info->ticks_per_second=image->ticks_per_second;
132043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
132053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
132063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
132073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
132083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
132093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
132103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
132113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
132123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
132133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
132143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1321503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
132164e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
132174e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
132183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
132193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
132203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
132213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
132223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
132233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
132253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
132273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
132280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
132313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
132343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
132363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
132370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
132403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
132443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
132463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
132483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
132490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
132523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
132553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
132573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
132580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
132613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
132643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
13265092ec8d083fedaedfb7792995e7ea42164553cffcristy     option=GetImageOption(image_info,"mng:need-cacheoff");
132663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
132673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
132693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
132703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
132733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
132753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
13276bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1327703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
132783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
132793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
132803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
132813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
132833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
132843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
132853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
132883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
132903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1329103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
132923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
132933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
132943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
132953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
132960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
132983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
132990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
133013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
133020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
133043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13306e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
13307e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
133080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
133103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13311e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
133120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
133143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13315e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
133163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
133183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
133193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
133213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
133223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
133233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
133243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
133253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
133283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
133303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1333103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
133320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
13334e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13335cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13336e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
133370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
13339e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13340cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13341cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
133420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
133443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
133453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
133463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
133493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
133513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
133533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
133543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
133553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
133563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1335703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1335835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
133593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
133603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
133613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
133623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
133643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
133663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
133673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
133693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
133703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
133713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
133723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1337303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
133743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1337535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1337635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
133773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1337835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1337935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
133803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1338135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1338235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
133833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1338435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1338535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
133863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
133873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
133883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
133893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1339116ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
133923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
133953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
133973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1339803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
133990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
134013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1340235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1340316ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
134040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1340535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1340616ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
134070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
134093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
134100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
134123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
134133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
134143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1341535ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1341616ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
134170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1341835ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1341916ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
134200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
134223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
134230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
134253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1342616ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1342716ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
134283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
134293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
134303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
134313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
134323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
134333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
134343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
134353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
134363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
134373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
1343817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy     if (write_mng && ((image->alpha_trait != UndefinedPixelTrait) ||
13439dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy         image->page.x > 0 || image->page.y > 0 || (image->page.width &&
134403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
134413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
134423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
134433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
134443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
134453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1344603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
134473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
134483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
134493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
134503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
134513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
134523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
134533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
134543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
134553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
134563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
134573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
134583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1345903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
134603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
134613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
134623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
134633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
134643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
134663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
134673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
134683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
134693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
13470bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
134713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
134723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
134743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
134753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
134763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
134773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
134783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1347903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
134800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13481bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
134823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1348316ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1348416ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1348516ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1348616ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1348716ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1348816ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
134893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
134900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
134923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
134933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
134943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
134953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
134973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
134983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
134993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
135003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
135013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
135023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
135033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
135043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
135053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
135063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
135073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
135083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
135093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
135103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
135113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
135123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
135133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
135143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
135153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
135163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
135173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
135183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
135193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
135203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
135213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
135223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
135233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
135243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
135253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
135263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
135273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
13528bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
135293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
135303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
135323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
135333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1353403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
135350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13536bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
135373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
135383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
135393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
135403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
135413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
135420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
135433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
135443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
135453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
135463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
135473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
135483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
135503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
135513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
135523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
135533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
135543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13555bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
135563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
135573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
135583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
135603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
135613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
135623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
135633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
135653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
135663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
135673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
135683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
135703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
135713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
135723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
135733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
135743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1357503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
135763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
135773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
135783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
135793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
135803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
135813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
135823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
135833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
135843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
135863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
135873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
135893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
135913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
135923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
135943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
135953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
135963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
135983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
136003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
136013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
136023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
136033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1360403812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
136053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
136063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
136073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
136083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
136093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
136103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
136113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
136123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
136133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
136143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
136153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1361603812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
136173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
136183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
136193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
136203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
136213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
136223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
136233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
136243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
136253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
136263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
136273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
136284e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
136293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
136303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
136313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
136323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
136333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
136343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
136353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
136363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
136373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
136383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
136393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
136403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
136413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
136423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
136433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
136443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1364516ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
136463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
136473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
136483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
136493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
136503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
136513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
136523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
136533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
136542f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13655b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
136568d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
136572f2e514554975d510c88df54de98c6cdc1080f1cglennrp
136582f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
136592f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
136602f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13661a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
136622f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
136632f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
136642f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
136652f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
136662f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
136672f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
136682f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
136692f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13670a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
136712f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
136722f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
136732f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
136742f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1367516ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
136763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
136773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
136783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
136803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
136813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
136823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
136833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
136843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
136853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
136863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
136883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
136893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
136900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
136950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
136973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
136983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
136993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
137003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
137013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
137023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
137033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
137043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1370503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
137063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
137073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
137083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
137093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
137103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
137113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
137123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
137133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
137140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
137153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
137163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
137170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
137183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
137193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13720d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1372139992b4dd9b12ef752d55b8e402c069698851f72glennrp
137223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
137233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
137243bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
137253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
137263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
137270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
137283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
137293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
137303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1373139992b4dd9b12ef752d55b8e402c069698851f72glennrp
137323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
137333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
137343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
137353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13736d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
137373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13738